.net core 中使用AutoMapper映射 简单易懂

一、为什么使用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

(注意啊老铁们,这里有个大坑啊,这个服务的注册顺序很重要啊,很重要,很重要,在本地运行没问题,

放到linux环境,哐哐的报错,找了一整天啊,记得放在最上面,ps:目前我放在最上面程序可以启动了,至于对不对。。。)

这就算完成了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 今天就到这儿了,使用应该已经没什么困难了,后期再补充一些底层的东西,怎么映射的,如何实现的等等。

 

posted @ 2020-07-22 18:03  srsly  阅读(3678)  评论(0编辑  收藏  举报