.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.DependencyInjectionAutoMapper.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; }
    }

 

posted @ 2020-10-15 00:27  冰乐  阅读(829)  评论(0编辑  收藏  举报