AutoMapper的匹配

1,智能匹配

     AutoMapper能够自动识别和匹配大部分对象属性:

  • 如果源类和目标类的属性名称相同,直接匹配,不区分大小写

    • 目标类型的CustomerName可以匹配源类型的Customer.Name
    • 目标类型的Total可以匹配源类型的GetTotal()方法

2,自定义匹配

    Mapper.CreateMap<CalendarEvent, CalendarEventForm>()                                                    //属性匹配,匹配源类中WorkEvent.Date到EventDate

    .ForMember(dest => dest.EventDate, opt => opt.MapFrom(src => src.WorkEvent.Date))

    .ForMember(dest => dest.SomeValue, opt => opt.Ignore())                                                 //忽略目标类中的属性

    .ForMember(dest => dest.TotalAmount, opt => opt.MapFrom(src => src.TotalAmount ?? 0))  //复杂的匹配

    .ForMember(dest => dest.OrderDate, opt => opt.UserValue<DateTime>(DateTime.Now));      //固定值匹配

直接匹配

源类的属性名称和目标类的属性名称相同(不区分大小写),直接匹配,Mapper.CreateMap<source,dest>();无需做其他处理,此处不再细述

Flattening

将一个复杂的对象模型拉伸为,或者扁平化为一个简单的对象模型,如下面这个复杂的对象模型:

        public class Order{private readonly IList<OrderLineItem> _orderLineItems = new List<OrderLineItem>();public Customer Customer { get; set; }public OrderLineItem[] GetOrderLineItems(){return _orderLineItems.ToArray();}public void AddOrderLineItem(Product product, int quantity){_orderLineItems.Add(new OrderLineItem(product, quantity));}public decimal GetTotal(){return _orderLineItems.Sum(li => li.GetTotal());}}public class Product{public decimal Price { get; set; }public string Name { get; set; }}public class OrderLineItem{public OrderLineItem(Product product, int quantity){Product = product;Quantity = quantity;}public Product Product { get; private set; }public int Quantity { get; private set; }public decimal GetTotal(){return Quantity * Product.Price;}}public class Customer{public string Name { get; set; }}

我们要把这一复杂的对象简化为OrderDTO,只包含某一场景所需要的数据:

        public class OrderDto{public string CustomerName { get; set; }public decimal Total { get; set; }}

运用AutoMapper转换:

            public void Example(){// Complex modelvar customer = new Customer{Name = "George Costanza"};var order = new Order{Customer = customer};var bosco = new Product{Name = "Bosco",Price = 4.99m};order.AddOrderLineItem(bosco, 15);// Configure AutoMappervar config = new MapperConfiguration(cfg => cfg.CreateMap<Order, OrderDto>());// Perform mappingvar mapper = config.CreateMapper();OrderDto dto = mapper.Map<Order, OrderDto>(order);dto.CustomerName.ShouldEqual("George Costanza");dto.Total.ShouldEqual(74.85m);}

可以看到只要设置下Order和OrderDto之间的类型映射就可以了,我们看OrderDto中的CustomerName和Total属性在领域模型Order中并没有与之相对性,AutoMapper在做解析的时候会按照PascalCase(帕斯卡命名法),CustomerName其实是由Customer+Name 得来的,是AutoMapper的一种映射规则;而Total是因为在Order中有GetTotal()方法,AutoMapper会解析“Get”之后的单词,所以会与Total对应。在编写代码过程中可以运用这种规则来定义名称实现自动转换。

Projection

Projection可以理解为与Flattening相反,Projection是将源对象映射到一个不完全与源对象匹配的目标对象,需要制定自定义成员,如下面的源对象:

        public class CalendarEvent{public DateTime EventDate { get; set; }public string Title { get; set; }}

目标对象:

        public class CalendarEventForm{public DateTime EventDate { get; set; }public int EventHour { get; set; }public int EventMinute { get; set; }public string Title { get; set; }}

AutoMapper配置转换代码:

            public void Example(){// Modelvar calendarEvent = new CalendarEvent{EventDate = new DateTime(2008, 12, 15, 20, 30, 0),Title = "Company Holiday Party"};var config = new MapperConfiguration(cfg =>{// Configure AutoMappercfg.CreateMap<CalendarEvent, CalendarEventForm>().ForMember(dest => dest.EventDate, opt => opt.MapFrom(src => src.EventDate.Date)).ForMember(dest => dest.EventHour, opt => opt.MapFrom(src => src.EventDate.Hour)).ForMember(dest => dest.EventMinute, opt => opt.MapFrom(src => src.EventDate.Minute));});// Perform mappingvar mapper = config.CreateMapper();CalendarEventForm form = mapper.Map<CalendarEvent, CalendarEventForm>(calendarEvent);form.EventDate.ShouldEqual(new DateTime(2008, 12, 15));form.EventHour.ShouldEqual(20);form.EventMinute.ShouldEqual(30);form.Title.ShouldEqual("Company Holiday Party");}

Configuration Validation

在进行对象映射的时候,有可能会出现属性名称或者自定义匹配规则不正确而又没有发现的情况,在程序执行时就报错,因此,AutoMapper提供的AssertConfigurationIsValid()方法来验证结构映射是否正确。

config.AssertConfigurationIsValid();如果映射错误,会报“AutoMapperConfigurationException”异常错误,就可以进行调试修改了

Lists and Array

AutoMapper支持的源集合类型包括:

  • IEnumerable
  • IEnumerable<T>
  • ICollection
  • ICollection<T>
  • IList
  • IList<T>
  • List<T>
  • Arrays

有一种情况是,在使用集合类型类型的时候,类型之间存在继承关系,例如下面我们需要转换的类型:

            //源对象public class ParentSource{public int Value1 { get; set; }}public class ChildSource : ParentSource{public int Value2 { get; set; }}//目标对象public class ParentDestination{public int Value1 { get; set; }}public class ChildDestination : ParentDestination{public int Value2 { get; set; }}

AutoMapper需要孩子映射的显式配置,AutoMapper配置转换代码:

                var config = new MapperConfiguration(cfg =>{cfg.CreateMap<ParentSource, ParentDestination>().Include<ChildSource, ChildDestination>();cfg.CreateMap<ChildSource, ChildDestination>();});var sources = new[]{new ParentSource(),new ChildSource(),new ParentSource()};var destinations = config.CreateMapper().Map<ParentSource[], ParentDestination[]>(sources);destinations[0].ShouldBeType<ParentDestination>();destinations[1].ShouldBeType<ChildDestination>();destinations[2].ShouldBeType<ParentDestination>();

注意在Initialize初始化CreateMap进行类型映射配置的时候有个Include泛型方法,签名为:“Include this configuration in derived types' maps”,大致意思为包含派生类型中配置,ChildSource是ParentSource的派生类,ChildDestination是ParentDestination的派生类,cfg.CreateMap<ParentSource, ParentDestination>().Include<ChildSource, ChildDestination>(); 这段代码是说明ParentSource和ChildSource之间存在的关系,并且要要显示的配置。

Nested mappings

嵌套对象映射,例如下面的对象:

       public class OuterSource{public int Value { get; set; }public InnerSource Inner { get; set; }}public class InnerSource{public int OtherValue { get; set; }}//目标对象public class OuterDest{public int Value { get; set; }public InnerDest Inner { get; set; }}public class InnerDest{public int OtherValue { get; set; }}

AutoMapper配置转换代码:

                var config = new MapperConfiguration(cfg =>{cfg.CreateMap<OuterSource, OuterDest>();cfg.CreateMap<InnerSource, InnerDest>();});config.AssertConfigurationIsValid();var source = new OuterSource{Value = 5,Inner = new InnerSource {OtherValue = 15}};var dest = config.CreateMapper().Map<OuterSource, OuterDest>(source);dest.Value.ShouldEqual(5);dest.Inner.ShouldNotBeNull();dest.Inner.OtherValue.ShouldEqual(15);

对于嵌套映射,只要指定下类型映射关系和嵌套类型映射关系就可以了,也就是这段代码:“Mapper.CreateMap<InnerSource, InnerDest>();” 其实我们在验证类型映射的时候加上Mapper.AssertConfigurationIsValid(); 这段代码看是不是抛出“AutoMapperMappingException”异常来判断类型映射是否正确。

参考资料

  • https://github.com/AutoMapper/AutoMapper/wiki
  • http://www.cnblogs.com/farb/p/AutoMapperContent.html

关于AutoMapper,陆续更新中...

转载于:https://www.cnblogs.com/yanyangxue2016/p/6229539.html

AutoMapper的介绍与使用(二)相关推荐

  1. 从Client应用场景介绍IdentityServer4(二)

    从Client应用场景介绍IdentityServer4(二) 原文:从Client应用场景介绍IdentityServer4(二) 本节介绍Client的ClientCredentials客户端模式 ...

  2. AIBlockChain:“知名博主独家讲授”人工智能创新应用竞赛【精选实战作品】之《基于计算机视觉、自然语言处理、区块链和爬虫技术的智能会议系统》软件系统案例的界面简介、功能介绍分享之二、会中智能

    AI&BlockChain:"知名博主独家讲授"人工智能创新应用竞赛[精选实战作品]之<基于计算机视觉.自然语言处理.区块链和爬虫技术的智能会议系统>软件系统案 ...

  3. 优秀的 Verilog/FPGA开源项目介绍(十二)- 玩FPGA不乏味

    优秀的 Verilog/FPGA开源项目介绍(十二)- 玩FPGA不乏味 Hello,大家好,之前给大家分享了大约一百多个关于FPGA的开源项目,涉及PCIe.网络.RISC-V.视频编码等等,这次给 ...

  4. 物联网方案介绍 - 智能水务—二次供水泵房物联网升级方案

    物联网方案介绍 - 智能水务-二次供水泵房物联网升级方案 1.  方案背景 目前城市的供水泵房,尤其是二次供水泵房,除了部分由自来水公司管理 外,多数由用水方负责建设管理,如物业公司.居委会.产权单位 ...

  5. c语言学习之基础知识点介绍(十二):结构体的介绍

    一.结构体的介绍 /* 语法:struct 结构体名{成员列表;};切记切记有分号!说明:成员列表就是指你要保存哪些类型的数据.注意:上面的语法只是定义一个新的类型,而这个类型叫做结构体类型.因为类型 ...

  6. Spring 使用介绍(十二)—— Spring Task

    一.概述 1.jdk的线程池和任务调用器分别由ExecutorService.ScheduledExecutorService定义,继承关系如下: ThreadPoolExecutor:Executo ...

  7. ubc计算机二学位培养方案,UT/McGill/UBC CS二学位(主要介绍多大二学位了)

    感觉这个帖子已经被我更新成多大二学位信息贴了,楼主平常不看贴的,有问题进群里问啊. ------------------08/2019更新---------------- 在霸霸的鼓励下更新帖子,沉迷 ...

  8. Netty介绍及实战(二)之IO与NIO和多路复用与零拷贝

    Netty介绍及实战(一) 一.Netty到底是什么?什么是多路复用?什么叫做零拷贝? Netty是一个NIO客户端服务器框架,可以快速.轻松地开发协议服务器和客户端等网络应用程序.它极大地简化和简化 ...

  9. 【PP生产订单】入门介绍(十二)

    这一讲我们主要来介绍一下生产订单的收货. Goods Receipt 成品入库: 下图则是收货后会产生哪些影响. 1.启用WMS模块的话会产生一个货仓转移需求. 2.打印收货单. 3.影响库存数量及价 ...

最新文章

  1. GNN教程:与众不同的预训练模型!
  2. 开发日记-20190704 关键词 读书笔记《Linux 系统管理技术手册(第二版)》DAY 10
  3. 小程序当中的文件类型,组织结构,配置,知识点等
  4. caffe problem
  5. php预处理查询数据库,php+mysqli使用预处理技术进行数据库查询的方法
  6. Docker最全教程——从理论到实战(九)
  7. 中国现代远程与继续教育网 统考 大学英语(B)考试大纲
  8. python读取音频文件的几种方式
  9. 计算机硬盘中没有设控制器,电脑设置硬盘为兼容模式
  10. PTES执行内容思维导图
  11. 深入浅出的讲解傅里叶变换(原文作者 韩昊)
  12. Final swfplayer安卓系统中播放网页中的播放flash动画
  13. HTML之在JavaScript中定义函数
  14. 狂神说---MySQL笔记
  15. 移动的帝国:日本移动互联网兴衰启示录
  16. bat文件刷屏,请规范命名
  17. 为啥翻唱的也特别好听呢,听J Fla 的 despacito
  18. 3DS Max 2014启动报错的解决方案
  19. 局域网通信软件MTalk
  20. pyltp包下载及使用

热门文章

  1. es springboot 不设置id_springboot整合ES_文档ID删除
  2. linux上php指向mysql_linux环境下 php如何配置mysql
  3. JAVA第六章第6题,java第六章例题源代码
  4. linux基本命令du,Linux常用操作命令汇总
  5. linux方法参数,Linux的sysctl 命令 参数
  6. 160 - 50 DueList.5
  7. python脚本:判断字符是否为中文
  8. html判断是安卓还是苹果手机,网页能够自己判断是pc端首页还是手机android和苹果。...
  9. linux查看网卡硬件 lsw,linux系统配置管理小测试试卷答案
  10. 【win10】局域网内两台win10共享文件夹