一、为什么使用AutoMapper
AutoMapper的功效其实就是把一个对象里面的value 映射 也就是复制到另一个对象,
比如我们有一个接口用来接收第三方数据的,接收了一个对象里面有很多字段,但是呢,
在我们需要保存到数据库的时候,字段名称不一样甚至有一些连类型都不一样
这就需要我们自己的model类与传递过来的model类进行映射,A.name =B.Name ,A.sex = B.gender 这样的代码就会增多
而且如果改动某一个字段或者删除某一个字段,那么就要把代码中这样的代码全部处理,灰常不方便,于是乎,我们选择了AutoMapper来映射
好处就是,名字相同的我们不需要处理,字段数量不对等也不会报错,代码整洁 不会左一块右一快。
接下来我们要在项目中使用AutoMapper来处理对象之间的映射。
在model层新建一个文件夹起名叫ViewModel 然后在下面 新建一个UserViewModel 实体类 代码如下
using System; using System.Collections.Generic; using System.Text; namespace WebApi.Core.Model.ViewModel { /// <summary> /// User数据的展示实体 /// </summary> 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; } } }
Service层中引用Nuget包 AutoMapper 和AutoMapper.Extensions.Microsoft.DependencyInjection
在Api层添加AutoMapper文件夹,然后添加映射配置文件CustomProfile.cs 用来匹配所有的映射对象关系
代码如下
using AutoMapper; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using WebApi.Core.Model; using WebApi.Core.Model.ViewModel; namespace WebApi.Core.Api.AutoMapper { public class CustomProfile:Profile { /// <summary> /// 配置构造函数,用来创建关系映射 /// </summary> public CustomProfile() { CreateMap<UsersModel, UserViewModel>(); } } }
注入服务 找到Startup.cs 在ConfiguService中 添加AutoMapper
这就算完成了AutoMapper的服务注入,接下来我们研究一下怎么用
首先在IUserService 添加一个方法GetUserDetails,代码如下
using System; using System.Collections.Generic; using System.Text; using System.Threading.Tasks; using WebApi.Core.IService.Base; using WebApi.Core.Model; using WebApi.Core.Model.ViewModel; namespace WebApi.Core.IService { public interface IUserService:IBaseService<UsersModel> { /// <summary> /// 测试sqlSugar 常用语句 /// </summary> void testSqlSugar(); /// <summary> /// 获取用户详情数据 /// </summary> /// <param name="id"></param> /// <returns></returns> Task<UserViewModel> GetUserDetails(int id); } }
在UserService中实例这个方法,代码如下
using AutoMapper; using System; using System.Collections.Generic; using System.Text; using System.Threading.Tasks; using WebApi.Core.IRepository; using WebApi.Core.IRepository.Base; using WebApi.Core.IService; using WebApi.Core.Model; using WebApi.Core.Model.ViewModel; using WebApi.Core.Service.Base; namespace WebApi.Core.Service { public class UserService:BaseService<UsersModel>,IUserService { //声明常量 private readonly IUserRepository userService; private readonly IMapper iMapper; public UserService(IBaseRepository<UsersModel> baseRepository, IUserRepository usersSer,IMapper mapper):base(baseRepository) { userService = usersSer; iMapper = mapper; } /// <summary> /// 测试sqlSugar 常用语句 /// </summary> public void testSqlSugar() { userService.testSqlSugar(); } /// <summary> /// 获取用户详情数据 /// </summary> /// <param name="id"></param> /// <returns></returns> public async Task<UserViewModel> GetUserDetails(int id) { var userInfo = await userService.QueryByID(id); if (userInfo != null) { UserViewModel model = iMapper.Map<UserViewModel>(userInfo); return model; } else { return null; } } } }
然后在UserORMController 加一个测试接口 代码如下
/// <summary> /// 测试automapper /// </summary> /// <returns></returns> [HttpPost] public async Task<IActionResult> AutoMapper(int id) { var userinfo = await userService.GetUserDetails(id); return Ok(userinfo); }
F5启动调试一下 看看结果,这就是AutoMapper了,当你的实体类越来越多 业务也越来越复杂的时候,就能体现出这种映射的好处了
这里注意一下 这个是单向映射的,不是双向哦,也就是说 UserModel,映射到UserViewModel 可以。。
反过来 把UserViewModel映射到UserModel里面是不行的,需要在加一个 CreateMap<UserViewModel,UserModel>
接下来我们在测试一下,名称不一样,在加上子类,在反向处理,获取一个json然后存入到数据库
首先新建一个文件夹取名字叫Entity 然后创建一个BaseEntity 类,在创建一个测试model类TestAutoMapper
代码 如下
using System; using System.Collections.Generic; using System.Text; namespace WebApi.Core.Model.Entity { public class BaseEntity { public int page { get; set; } public int size { get; set; } } }
using System; using System.Collections.Generic; using System.Text; using WebApi.Core.Model.Entity; namespace WebApi.Core.Model { public class TestAutoMapper:BaseEntity { /// <summary> /// 对应UserId /// </summary> public int id { get; set; } /// <summary> /// 姓名 /// </summary> public string UserName { get; set; } /// <summary> /// 对应Age /// </summary> public int yearDate { get; set; } /// <summary> /// 存一个list 存放 子表 /// </summary> public List<TokenModel> tokenList { get; set; } } }
然后在IUserService 和UserService 添加方法,代码如下
/// <summary> /// 获取数据插入到数据库 放到IUserService里面 /// </summary> /// <param name="userviewmodel"></param> /// <returns></returns> Task<bool> AddUserByViewModel(TestAutoMapper testmodel);
/// <summary> /// 获取数据插入到数据库 放到UserService里面 /// </summary> /// <param name="userviewmodel"></param> /// <returns></returns> public async Task<bool> AddUserByViewModel(TestAutoMapper testmodel) { if (testmodel != null) { UsersModel userinfo = iMapper.Map<UsersModel>(testmodel); return await userService.Add(userinfo); } else { return false; } }
最后在配置一下AutoMapper映射 在Api 的 CustomProfile.cs 里面代码如下
using AutoMapper; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using WebApi.Core.Model; using WebApi.Core.Model.ViewModel; namespace WebApi.Core.Api.AutoMapper { public class CustomProfile:Profile { /// <summary> /// 配置构造函数,用来创建关系映射 /// </summary> public CustomProfile() { CreateMap<UsersModel, UserViewModel>() .ForMember(d=>d.Phone,o=>o.MapFrom(s=>s.Age)); CreateMap<TestAutoMapper, UsersModel>() .ForMember(d=>d.UserId,o=>o.MapFrom(s=>s.id)) .ForMember(d=>d.Age,o=>o.MapFrom(s=>s.yearDate)) .ForMember(d=>d.UserName,o=>o.MapFrom(s=>JsonConvert.SerializeObject(s.tokenList))); } } }
在UserORMController里面添加接口测试
/// <summary> /// 测试AutoMapper反向映射,插入到数据库 /// </summary> /// <param name="testmodel"></param> /// <returns></returns> [HttpPost] public async Task<IActionResult> AutoMapperReverse(TestAutoMapper testmodel) { var result = await userService.AddUserByViewModel(testmodel); return Ok(result); }
我们按F5 调试一下,可以看到已经成功了,其实很简单,就是把一个对象的值,复制到另一个对象中,其中的值可以随意转变,灵活控制
数据也成功的插入进去了,不管是继承了什么子类 只要是名字一样的autoMapper 都会找到 然后映射过去,如果不想那么做,就单独映射那个字段
这个AutoMapper 今天就到这儿了,使用应该已经没什么困难了,后期再补充一些底层的东西,怎么映射的,如何实现的等等。