.Net Core3.0 WebApi 項目框架搭建:目錄
不使用AutoMapper
Model層的viewmodel文件夾新建UserViewModel.cs
public class UserViewModel { /// <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()方法,返回類型是UserViewModel
public interface IUserService : IBaseService<User> { /// <summary> /// 獲取用戶數量 /// </summary> /// <returns></returns> Task<int> GetCount(); /// <summary> /// 獲取用戶詳情 /// </summary> /// <param name="id"></param> /// <returns></returns> Task<UserViewModel> GetUserDetails(int id); }
public async Task<UserViewModel> GetUserDetails(int id) { var userinfo = await userDal.QueryByID(id); if (userinfo != null) { UserViewModel model = new UserViewModel() { UserId = userinfo.UserId, UserName = userinfo.UserName, Address = "北京市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
在接口層Blog.Core 中,添加文件夾AutoMapper,然后添加映射配置文件 CustomProfile.cs,用來匹配所有的映射對象關系。
public class CustomProfile : Profile { /// <summary> /// 配置構造函數,用來創建關系映射 /// </summary> public CustomProfile() { CreateMap<User, UserViewModel>(); } }
Startup中,注入服務
services.AddAutoMapper(typeof(Startup));
修改Service層
修改上邊UserServices.cs 中GetUserDetails方法中的賦值,改用AutoMapper,並用構造函數注。
private readonly IUserRepository userDal; private readonly IMapper iMapper; public UserService(IBaseRepository<User> baseRepository, IUserRepository userRepository, IMapper IMapper) : base(baseRepository) { userDal = userRepository; iMapper = IMapper; } public async Task<UserViewModel> GetUserDetails(int id) { var userinfo = await userDal.QueryByID(id); if (userinfo != null) { //UserViewModel model = new UserViewModel() //{ // UserId = userinfo.UserId, // UserName = userinfo.UserName, // Address = "北京市xx區xx小區", // Age = userinfo.Age, // Birthday = "1996-06-26", // Phone = "13888888888" //}; UserViewModel model = iMapper.Map<UserViewModel>(userinfo); model.Address = "北京市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); }
F5運行調試,可以看到斷點處已經轉換成功了
復雜深拷貝映射
有的小伙伴會問,你這個這個簡單,都是相同字段的,那當然很方便啦,要是一個復雜的,比如屬性名字不一樣的,或者說有子類等嵌入型的咋辦?放心,一樣是可以的。
1、屬性名稱不一樣
CreateMap<Student, StudentViewModel>() .ForMember(d => d.CountyName, o => o.MapFrom(s => s.County)) .ForMember(d => d.ProvinceName, o => o.MapFrom(s => s.Province));
2、如果是還有子類的復雜類型
CreateMap<Student, StudentViewModel>() .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 StudentViewModel { 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; } }