.Net Core3.0 WebApi 十:使用AutoMapper实现模型映射
.Net Core3.0 WebApi 目录
不使用AutoMapper
Models层的Reponse中新建User文件夹,新建UserResponse.cs
namespace WebApi.Core.Models.Reponse.User { /// <summary> /// user响应实体 /// </summary> public class UserResponse { /// <summary> /// ID /// </summary> public int UserId { get; set; } /// <summary> /// 用户名 /// </summary> public string UserName { get; set; } /// <summary> /// 年龄 /// </summary> public int? Age { get; set; } /// <summary> /// 生日 /// </summary> public string Birthday { get; set; } /// <summary> /// 手机 /// </summary> public string Phone { get; set; } /// <summary> /// 地址 /// </summary> public string Address { get; set; } } }
IUserServices.cs和 类UserServices.cs中,添加GetUserDetails()方法,返回类型是UserResponse
public interface IUserService : IBaseServices<UserNew> { /// <summary> /// 获取用户数量 /// </summary> /// <returns></returns> Task<int> GetCount(); /// <summary> /// 获取用户详情 /// </summary> /// <param name="id"></param> /// <returns></returns> Task<UserResponse> GetUserDetails(int id); }
public async Task<UserResponse> GetUserDetails(int id) { //var userinfo = await userDal.QueryByID(id); var userinfo = new UserNew { UserId = id, UserName = "bingle", Age = 18 }; if (userinfo != null) { UserResponse model = new UserResponse() { UserId = userinfo.UserId, UserName = userinfo.UserName, Address = "xx市xx区xx小区", Age = userinfo.Age, Birthday = "1996-06-26", Phone = "13888888888" }; return model; } else { return null; } }
因为我这边只是写了个demo,实体类字段还不是很多,真正的开发起来肯定有很多个字段,而且这种方法系统会有很多,写起来也很累人,后期维护也不方便,要多一个字段少一个字段,要去每个地方去修改。
什么是AutoMapper
它是一种对象与对象之间的映射器,让AutoMapper有意思的就是在于它提供了一些将类型A映射到类型B这种无聊的实例,只要B遵循AutoMapper已经建立的惯例,那么大多数情况下就可以进行相互映射了。
引入 AutoMapper 的相关包
Services项目中引用Nuget包,AutoMapper 和 AutoMapper.Extensions.Microsoft.DependencyInjection,AutoMapper.Extensions.Microsoft.DependencyInjection,这个是用来配合依赖注入的。
添加映射文件 CustomProfile.cs
在API层 中,添加文件夹AutoMapper,然后添加映射配置文件 CustomProfile.cs,用来匹配所有的映射对象关系。
namespace WebApi.Core.Api.AutoMapper { public class CustomProfile : Profile { /// <summary> /// 配置构造函数,用来创建关系映射 /// </summary> public CustomProfile() { CreateMap<UserNew, UserResponse>(); } } }
Startup中,注入服务
//注册automapper services.AddAutoMapper(typeof(Startup));
修改Service层
修改上边UserServices.cs 中GetUserDetails方法中的赋值,改用AutoMapper,并用构造函数注。
namespace WebApi.Core.Services { public class UserService : BaseServices<UserNew>, IUserService { private readonly IUserRepository userDal; private readonly IMapper iMapper; public UserService(IBaseRepository<UserNew> baseRepository, IUserRepository userRepository, IMapper IMapper) : base(baseRepository) { userDal = userRepository; iMapper = IMapper; } public Task<int> GetCount() { return Task.FromResult(101); } public async Task<UserResponse> GetUserDetails(int id) { //var userinfo = await userDal.QueryByID(id); var userinfo = new UserNew { UserId = id, UserName = "bingle", Age = 18 }; if (userinfo != null) { //UserResponse model = new UserResponse() //{ // UserId = userinfo.UserId, // UserName = userinfo.UserName, // Address = "xx市xx区xx小区", // Age = userinfo.Age, // Birthday = "1996-06-26", // Phone = "13888888888" //}; UserResponse model = iMapper.Map<UserResponse>(userinfo); model.Address = "xx市xx区xx小区"; model.Birthday = "1996-06-26"; model.Phone = "13888888888"; return model; } else { return null; } } } }
测试AutoMapper
添加一个接口测试automapper
/// <summary> /// 测试automapper /// </summary> /// <returns></returns> [HttpGet] public async Task<IActionResult> AutoMapper(int id) { var userinfo = await _userService.GetUserDetails(id); return Ok(userinfo); }
运行调试,可以看到断点处已经转换成功了
复杂深拷贝映射
1、属性名称不一样
CreateMap<Student, StudentResponse>() .ForMember(d => d.CountyName, o => o.MapFrom(s => s.County)) .ForMember(d => d.ProvinceName, o => o.MapFrom(s => s.Province));
2、如果是还有子类的复杂类型
CreateMap<Student, StudentResponse>() .ForMember(d => d.County, o => o.MapFrom(s => s.Address.County)) .ForMember(d => d.Province, o => o.MapFrom(s => s.Address.Province)) .ForMember(d => d.City, o => o.MapFrom(s => s.Address.City)) .ForMember(d => d.Street, o => o.MapFrom(s => s.Address.Street)) ; public class Student : Entity { public string Name { get; private set; } public string Email { get; private set; } public string Phone { get; private set; } public DateTime BirthDate { get; private set; } public Address Address { get; private set; } } public class StudentResponse { public Guid Id { get; set; } public string Name { get; set; } public string Email { get; set; } public DateTime BirthDate { get; set; } public string Phone { get; set; } public string Province { get; set; } public string City { get; set; } public string County { get; set; } public string Street { get; set; } }