zoukankan      html  css  js  c++  java
  • 在 ASP.NET Core 项目中使用 AutoMapper 进行实体映射

    先说一说DTO

    DTO是个什么东东?

    DTO(Data Transfer Object)就是数据传输对象,说白了就是一个对象,只不过里边全是数据而已。

    为什么要用DTO?

    1、DTO更注重数据,对领域对象进行合理封装,从而不会将领域对象的行为过分暴露给表现层

    2、DTO是面向UI的需求而设计的,而领域模型是面向业务而设计的。因此DTO更适合于和表现层的交互,通过DTO我们实现了表现层与领域Model之间的解耦,因此改动领域Model不会影响UI层

    3、DTO说白了就是数据而已,不包含任何的业务逻辑,属于瘦身型的对象,使用时可以根据不同的UI需求进行灵活的运用

    AutoMapper

    现在我们既然知道了使用DTO的好处,那么我们肯定也想马上使用它,但是这里会牵扯一个问题:怎样实现DTO和领域Model之间的转换?

    有两个思路,我们要么自己写转换代码,要么使用工具。不过就应用而言,我还是觉得用工具比较简单快捷,那就使用工具吧。其实这样的转换工具很多,不过我还是决定使用AutoMapper,因为它足够轻量级,而且也非常流行,国外的大牛们都使用它。使用AutoMapper可以很方便的实现DTO和领域Model之间的转换,它是一个强大的Object-Object Mapping工具。

    一、如何添加AutoMapper到项目中?

    在vs中使用打开工具-库程序包管理器-程序包管理控制平台,输入“Install-Package AutoMapper”命令,就可以把AutoMapper添加到项目中了~

    二、吃点栗子

    栗子1(两个类型之间的映射)

    1 Mapper.CreateMap<AddressDto, Address>();
    2              AddressDto dto = new AddressDto
    3               {
    4                   Country = "China",
    5                   City = "ShangHai",
    6                   Street = "JinZhong Street"
    7               };
    8 Address address = Mapper.Map<AddressDto,Address>(Dto);

    栗子2(两个映射的对象有部分字段名称不一样)

    AddressDto到Address的映射,AddressDto的字段CountryName要对应Address的字段Country:

     1 Mapper.CreateMap<AddressDto, Address>(). ForMember(d => d.Country, opt => opt.MapFrom(s => s.CountryName)); 

    栗子3(列表类型之间的映射)

    源类型List<Address>,目标类型List<AddressDto>:

    AutoMapper.Mapper.CreateMap< Address, AddressDto >();
    var addressDtoList = AutoMapper.Mapper.Map<List< Address >, List< AddressDto >>( addressList);

    栗子4(映射在增改查中的应用)

     1 public class ProductBll
     2 
     3 {
     4         Public IProductRepository productRepository{ set; get; }
     5         public ProductDTO CreateProduct(ProductDTO productDTO)
     6         {
     7             Mapper.CreateMap<ProductDTO, Product>();
     8             Product product = Mapper.Map<ProductDTO, Product>(productDTO);
     9             productRepository.AddProduct(product);
    10             return productDTO;
    11         }
    12 
    13         public List<ProductDTO> GetProduct()
    14         {
    15             Mapper.CreateMap<Product, ProductDTO>();
    16             List<ProductDTO> arr = new List<ProductDTO>();
    17             productRepository.GetProduct().ForEach(i =>
    18             {
    19                 arr.Add(Mapper.Map<Product, ProductDTO>(i));
    20             });
    21             return arr;
    22         }
    23 
    24          public ProductDTO ModifyProduct(ProductDTO productDTO)
    25         {
    26             Mapper.CreateMap<ProductDTO, Product>();
    27             Product product = Mapper.Map<ProductDTO, Product>(productDTO);
    28             productRepository.ModifyProduct(product);
    29             return productDTO;
    30         }
    31 }

    三、让AutoMapper使用变得简单

    吃过上面的栗子,你觉得怎么样呢?如果想继续吃,那就去查看AutoMapper的具体API文档吧!倘若在项目中真正要用的时候,我觉得还是应该对AutoMapper的方法进行一些整理,最好能够封装一下,这里我通过扩展方法的形式将其封装为AutoMapperHelper,这样以后使用AutoMapper就变的SO EASY了~

     1 using System.Collections;
     2 using System.Collections.Generic;
     3 using System.Data;
     4 using AutoMapper;
     5 namespace Infrastructure.Utility
     6 
     7 {
     8     /// <summary>
     9     /// AutoMapper扩展帮助类
    10     /// </summary>
    11     public static class AutoMapperHelper
    12     {
    13         /// <summary>
    14         ///  类型映射
    15         /// </summary>
    16         public static T MapTo<T>(this object obj)
    17         {
    18             if (obj == null) return default(T);
    19             Mapper.CreateMap(obj.GetType(), typeof(T));
    20             return Mapper.Map<T>(obj);
    21         }
    22         /// <summary>
    23         /// 集合列表类型映射
    24         /// </summary>
    25         public static List<TDestination> MapToList<TDestination>(this IEnumerable source)
    26         {
    27             foreach (var first in source)
    28             {
    29                 var type = first.GetType();
    30                 Mapper.CreateMap(type, typeof(TDestination));
    31                 break;
    32             }
    33             return Mapper.Map<List<TDestination>>(source);
    34         }
    35         /// <summary>
    36         /// 集合列表类型映射
    37         /// </summary>
    38         public static List<TDestination> MapToList<TSource, TDestination>(this IEnumerable<TSource> source)
    39         {
    40             //IEnumerable<T> 类型需要创建元素的映射
    41             Mapper.CreateMap<TSource, TDestination>();
    42             return Mapper.Map<List<TDestination>>(source);
    43         }
    44         /// <summary>
    45         /// 类型映射
    46         /// </summary>
    47         public static TDestination MapTo<TSource, TDestination>(this TSource source, TDestination destination)
    48             where TSource : class
    49             where TDestination : class
    50         {
    51            if (source == null) return destination;
    52             Mapper.CreateMap<TSource, TDestination>();
    53             return Mapper.Map(source, destination);
    54         }
    55         /// <summary>
    56         /// DataReader映射
    57         /// </summary>
    58         public static IEnumerable<T> DataReaderMapTo<T>(this IDataReader reader)
    59         {
    60             Mapper.Reset();
    61             Mapper.CreateMap<IDataReader, IEnumerable<T>>();
    62             return Mapper.Map<IDataReader, IEnumerable<T>>(reader);
    63         }
    64     }
    65 }

    你可以像下面的栗子这样使用:

    //对象映射
    ShipInfoModel  shipInfoModel =  ShipInfo.MapTo<ShipInfoModel>();
    //列表映射
    List< ShipInfoModel > shipInfoModellist = ShipInfoList.MapToList<ShipInfoModel>();

    小结

    在项目中多使用DTO实现表现层与领域Model的解耦,用AutoMapper来实现DTO与领域Model的相互转换,让AutoMapper在你的项目里飞一会儿

  • 相关阅读:
    数据库规范化:闭包求解
    Django restframework解析器组件增加及源码分析
    Nuxt
    window环境下安装homestead后,共享文件夹无法共享文件
    30岁女IT月薪3W的背后:从数据报表到数仓、中台,这工具帮了大忙
    Markdown字体颜色、字号、大小修改(含颜色表)
    数据库规范化:函数依赖,三范式的区别
    数据库作业20:数据库恢复技术
    How Many Processes Should Be Set For The Receiving Transaction Manager (RTM)
    How to Create a Java Concurrent Program
  • 原文地址:https://www.cnblogs.com/zhao987/p/12627411.html
Copyright © 2011-2022 走看看