AutoMapper的介绍与使用(二)

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/394286.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

站长快讯 WordPress跨站攻击漏洞修补

WordPress中发现一些漏洞&#xff0c;攻击者利用该漏洞可以发起跨站脚本攻击&#xff0c;绕过WordPress安全性限制&#xff0c;获取较为敏感的修订历史记录的信息&#xff0c;或者绑架站点以用于DDoS攻击。 CVE ID CVE-2015-8834 CVE-2016-5832 CVE-2016-5834 CVE-2016-5835 C…

畅通无阻的公式:乘员组从几乎破产变成了吸引500万游客的方式

How could you go from almost no traction and running out of money, to getting millions of visitors to your website?您怎么能从几乎没有牵引力和资金用尽的角度&#xff0c;如何吸引数百万的网站访问者&#xff1f; You could do like Crew accidentally did with Uns…

leetcode1302. 层数最深叶子节点的和(深度优先搜索)

给你一棵二叉树&#xff0c;请你返回层数最深的叶子节点的和。 代码 class Solution {int[] depthnew int[]{Integer.MIN_VALUE,0};//记录最深层数和对应的和public int deepestLeavesSum(TreeNode root) {if(rootnull) return 0;deep(root,0);return depth[1];}public void d…

Python笔记 【无序】 【五】

描述符 将某种特殊类型的类【只要实现了以下或其中一个】的实例指派给另一个类的属性 1.__get__(self,instance,owner)//访问属性&#xff0c;返回属性的值 2.__set__(self,instance,value)//将在属性分配【即赋值】中调用&#xff0c;不返回任何内容 3.__delete__&#xff08;…

化工图纸中LISP_化工设备厂参展模型设计制作

最近这个案子是受某化工设备企业委托做四套设备模型 用来参加展会在模型制作过程中&#xff0c;这类案例经常遇到。但是客户所提供的CAD图纸&#xff0c;往往是实物尺寸在进行缩放的过程中常会造成过薄和过于精细的情况出现眼下技术小哥就遇到这类情况让我们先看看客户提供的C…

社交大佬们的数据“大”在哪里?

文章讲的是社交大佬们的数据“大”在哪里&#xff0c;“别说忙&#xff0c;没工夫看书&#xff0c;你那刷FB/朋友圈的工夫腾出来&#xff0c;保证每周啃下一本”&#xff0c;小编身边总充斥着这样的“训话”。 额&#xff0c;奈何我每天的工作离不开从社交媒体中获取信息&#…

微信支付JsAPI

https://pay.weixin.qq.com/wiki/doc/api/download/WxpayAPI_php_v3.zip 下载获取微信支付demo压缩包打开压缩包&#xff0c;并将其中 WxpayAPI_php_v3\example下的 jsapi.php log.php WxPay.JsApiPay.php WxPay.MicroPay.php WxPay.NativePay.php 解压缩到根目录 tellingtent/…

mysql 多数据源访问_通过Spring Boot配置动态数据源访问多个数据库的实现代码

之前写过一篇博客《SpringMybatisMysql搭建分布式数据库访问框架》描述如何通过SpringMybatis配置动态数据源访问多个数据库。但是之前的方案有一些限制(原博客中也描述了)&#xff1a;只适用于数据库数量不多且固定的情况。针对数据库动态增加的情况无能为力。下面讲的方案能支…

我如何将Google I / O 2018的兴奋带给尼日利亚沃里的115个人

Google Developer Group Warri的第一个I / O扩展事件的故事 (A tale of Google Developer Group Warri’s first I/O Extended event) Google I/O is one of the largest developer festivals in the tech ecosystem. I am the lead organizer for the Google Developer Group …

菜鸟postman接口测试_postman 接口测试(转)

本文转载自testerhome&#xff1b;作者&#xff1a;xinxi1990 &#xff1b;原文链接&#xff1a;https://testerhome.com/topics/18719&#xff1b;转载以分享知识为目的&#xff0c;著作权归原作者所有&#xff0c;如有侵权&#xff0c;请联系删除。postman使用创建用例集启动…

求绝对值最小的数

题目 有一个升序排列的数组&#xff0c;数组中可能有正数&#xff0c;负数或0. 求数组中元素的绝对值最小的数. 例如 数组{-10&#xff0c; 05&#xff0c; 02 &#xff0c;7&#xff0c;15&#xff0c;50} 绝对值最小的是-2 解答 #include <bits/stdc.h> using namespac…

leetcode面试题 04.02. 最小高度树(深度优先搜索)

给定一个有序整数数组&#xff0c;元素各不相同且按升序排列&#xff0c;编写一个算法&#xff0c;创建一棵高度最小的二叉搜索树。 public TreeNode sortedArrayToBST(int[] nums) {if(nums.length0) return null;return BST(nums,0,nums.length-1);}public TreeNode BST(int[…

IT团队如何赢得尊重?

本文讲的是IT团队如何赢得尊重,在传统观念中&#xff0c;作为企业的IT人&#xff0c;似乎都有一种挥之不去的消极情绪&#xff1a;能够为企业带来直接利益的业务部门才是企业核心&#xff0c;而作为技术支撑的IT部门&#xff0c;则是作为附属而存在。 我们经常也会听到一些企业…

mysql 官方镜像_运行官方mysql 镜像

//目前最新的为mysql 8sudo docker run -itd --restart unless-stopped --nethost --name mysql -p3306:3306 -e MYSQL_ROOT_PASSWORDroot mysqlmysql 官方docker 需要重新设置密码&#xff0c;否则无法远程连接step1 : docker exec -it [容器id] /bin/bashstep2 : 登陆mysql &…

我如何使用React,Redux-Saga和Styled Components构建NBA球员资料获取器

by Jonathan Puc乔纳森普克(Jonathan Puc) 我如何使用React&#xff0c;Redux-Saga和Styled Components构建NBA球员资料获取器 (How I built an NBA player profile fetcher with React, Redux-Saga, and Styled Components) Hello, all! It’s been a while since I built so…

vb 数组属性_VB中菜单编辑器的使用讲解及实际应用

大家好&#xff0c;今天我们共同来学习VB中菜单方面的知识。VB中菜单的基本作用有两个&#xff1a;1、提供人机对话的界面&#xff0c;以便让使用者选择应用系统的各种功能&#xff1b;2、管理应用系统&#xff0c;控制各种功能模块的运行。在实际应用中&#xff0c;菜单可分为…

《JAVA程序设计》_第七周学习总结

一、学习内容 1.String类——8,1知识 Java专门提供了用来处理字符序列的String类。String类在java.lang包中&#xff0c;由于java.lang包中的类被默认引入&#xff0c;因此程序可以直接使用String类。需要注意的是Java把String类声明为final类&#xff0c;因此用户不能扩展Stri…

leetcode109. 有序链表转换二叉搜索树(深度优先搜索/快慢指针)

给定一个单链表&#xff0c;其中的元素按升序排序&#xff0c;将其转换为高度平衡的二叉搜索树。 本题中&#xff0c;一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。 解题思路 先将链表转换成数组&#xff0c;再构造二叉搜索树 代码 …

NeHe OpenGL教程 第三十七课:卡通映射

转自【翻译】NeHe OpenGL 教程 前言 声明&#xff0c;此 NeHe OpenGL教程系列文章由51博客yarin翻译&#xff08;2010-08-19&#xff09;&#xff0c;本博客为转载并稍加整理与修改。对NeHe的OpenGL管线教程的编写&#xff0c;以及yarn的翻译整理表示感谢。 NeHe OpenGL第三十七…

SDN交换机在云计算网络中的应用场景

SDN的技术已经发展了好几年了&#xff0c;而云计算的历史更长&#xff0c;两者的结合更是作为SDN的一个杀手级应用在近两年炒得火热&#xff0c;一些知名咨询公司的关于SDN逐年增加的市场份额的论断&#xff0c;也主要是指SDN在云计算网络中的应用。 关于SDN在云计算网络中的应…