在上一篇文章中我们构造出了完整的应用场景,包括我们的Model、Dto以及它们之间的转换规则。下面就可以卷起袖子,开始我们的AutoMapper之旅了。 
【二】以Convention方式实现零配置的对象映射 
我们的AddressDto和Address结构完全一致,且字段名也完全相同。对于这样的类型转换,AutoMapper为我们提供了Convention,正如它的官网上所说的:

引用
AutoMapper uses a convention-based matching algorithm to match up source to destination values.

我们要做的只是将要映射的两个类型告诉AutoMapper(调用Mapper类的Static方法CreateMap并传入要映射的类型):

  1. Mapper.CreateMap<AddressDto, Address>();

然后就可以交给AutoMapper帮我们搞定一切了:

  1. AddressDto dto = new AddressDto
  2. {
  3. Country = "China",
  4. City = "Beijing",
  5. Street = "Dongzhimen Street",
  6. PostCode = "100001"
  7. };
  8. Address address = Mapper.Map<AddressDto,Address>(Dto);
  9. address.Country.ShouldEqual("China");
  10. address.City.ShouldEqual("Beijing");
  11. address.Street.ShouldEqual("Dongzhimen Street");
  12. address.PostCode.ShouldEqual("100001");

如果AddressDto中有值为空的属性,AutoMapper在映射的时候会把Address中的相应属性也置为空:

  1. Address address = Mapper.Map<AddressDto,Address>(new AddressDto
  2. {
  3. Country = "China"
  4. });
  5. address.City.ShouldBeNull();
  6. address.Street.ShouldBeNull();
  7. address.PostCode.ShouldBeNull();

甚至如果传入一个空的AddressDto,AutoMapper也会帮我们得到一个空的Address对象。

  1. Address address = Mapper.Map<AddressDto,Address>(null);
  2. address.ShouldBeNull();

千万不要把这种Convention的映射方式当成“玩具”,它在映射具有相同字段名的复杂类型的时候还是具有相当大的威力的。 
例如,考虑我们的BookStoreDto到BookStore的映射,两者的字段名称完全相同,只是字段的类型不一致。如果我们定义好了BookDto到Book的映射规则,再加上上述Convention方式的AddressDto到Address的映射,就可以用“零配置”实现BookStoreDto到BookStore的映射了:

  1. IMappingExpression<BookDto, Book> expression = Mapper.CreateMap<BookDto,Book>();
  2. // Define mapping rules from BookDto to Book here
  3. Mapper.CreateMap<AddressDto, Address>();
  4. Mapper.CreateMap<BookStoreDto, BookStore>();

然后我们就可以直接转换BookStoreDto了:

  1. BookStoreDto dto = new BookStoreDto
  2. {
  3. Name = "My Store",
  4. Address = new AddressDto
  5. {
  6. City = "Beijing"
  7. },
  8. Books = new List<BookDto>
  9. {
  10. new BookDto {Title = "RESTful Web Service"},
  11. new BookDto {Title = "Ruby for Rails"},
  12. }
  13. };
  14. BookStore bookStore = Mapper.Map<BookStoreDto,BookStore>(dto);
  15. bookStore.Name.ShouldEqual("My Store");
  16. bookStore.Address.City.ShouldEqual("Beijing");
  17. bookStore.Books.Count.ShouldEqual(2);
  18. bookStore.Books.First().Title.ShouldEqual("RESTful Web Service");
  19. bookStore.Books.Last().Title.ShouldEqual("Ruby for Rails");

【三】定义类型间的简单映射规则 
前面我们看了Convention的映射方式,客观的说还是有很多类型间的映射是无法通过简单的Convention方式来做的,这时候就需要我们使用Configuration了。好在我们的Configuration是在代码中以“强类型”的方式来写的,比写繁琐易错的xml方式是要好的多了。 
先来看看BookDto到Publisher的映射。 
回顾一下前文中定义的规则:BookDto.Publisher -> Publisher.Name。 
在AutoMapperzhong,我们可以这样映射:

  1. var map = Mapper.CreateMap<BookDto,Publisher>();
  2. map.ForMember(d => d.Name, opt => opt.MapFrom(s => s.Publisher));

AutoMapper使用ForMember来指定每一个字段的映射规则:

引用
The each custom member configuration uses an action delegate to configure each member.

还好有强大的lambda表达式,规则的定义简单明了。

此外,我们还可以使用ConstructUsing的方式一次直接定义好所有字段的映射规则。例如我们要定义BookDto到第一作者(Author)的ContactInfo的映射,使用ConstructUsing方式,我们可以:

  1. var map = Mapper.CreateMap<BookDto,ContactInfo>();
  2. map.ConstructUsing(s => new ContactInfo
  3. {
  4. Blog = s.FirstAuthorBlog,
  5. Email = s.FirstAuthorEmail,
  6. Twitter = s.FirstAuthorTwitter
  7. });

然后,就可以按照我们熟悉的方式来使用了:

  1. BookDto dto = new BookDto
  2. {
  3. FirstAuthorEmail = "matt.rogen@abc.com",
  4. FirstAuthorBlog = "matt.amazon.com",
  5. };
  6. ContactInfo contactInfo = Mapper.Map<BookDto, ContactInfo>(dto);

如果需要映射的2个类型有部分字段名称相同,又有部分字段名称不同呢?还好AutoMapper给我们提供的Convention或Configuration方式并不是“异或的”,我们可以结合使用两种方式,为名称不同的字段配置映射规则,而对于名称相同的字段则忽略配置。 
例如对于前面提到的AddressDto到Address的映射,假如AddressDto的字段Country不叫Country叫CountryName,那么在写AddressDto到Address的映射规则时,只需要:

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

对于City、Street和PostCode无需定义任何规则,AutoMapper仍然可以帮我们进行正确的映射。

使用AutoMapper实现Dto和Model的自由转换(中)的更多相关文章

  1. 使用AutoMapper实现Dto和Model之间自由转换

    应用场景:一个Web应用通过前端收集用户的输入成为Dto,然后将Dto转换成领域模型并持久化到数据库中.另一方面,当用户请求数据时,我们又需要做相反的工作:将从数据库中查询出来的领域模型以相反的方式转 ...

  2. 使用AutoMapper实现Dto和Model的自由转换

    AutoMapper是一个.NET的对象映射工具. 项目地址:https://github.com/AutoMapper/AutoMapper. 帮助文档:https://github.com/Aut ...

  3. 使用AutoMapper实现Dto和Model的自由转换(上)

    在实际的软件开发项目中,我们的“业务逻辑”常常需要我们对同样的数据进行各种变换.例如,一个Web应用通过前端收集用户的输入成为Dto,然后将Dto转换成领域模型并持久化到数据库中.另一方面,当用户请求 ...

  4. 使用AutoMapper实现Dto和Model的自由转换(下)

    书接上文.在上一篇文章中我们讨论了使用AutoMapper实现类型间1-1映射的两种方式——Convention和Configuration,知道了如何进行简单的OO Mapping.在这个系列的最后 ...

  5. AutoMapper完成Dto与Model的转换

    在实际的软件开发项目中,我们的“业务逻辑”常常需要我们对同样的数据进行各种变换. 例如,一个Web应用通过前端收集用户的输入成为Dto,然后将Dto转换成领域模型并持久化到数据库中.相反,当用户请求数 ...

  6. 自制AutoMapper实现DTO到持久层Entity的转换

    自制AutoMapper实现DTO到持久层Entity的转换 项目中经常涉及到页面DTO更新,保存到数据库的操作,这就必然牵扯到DTO和持久层对象的转换,常见的第三方库有: java:dozer .n ...

  7. Swift3.0语言教程字符串与URL的数据转换与自由转换

    Swift3.0语言教程字符串与URL的数据转换与自由转换 Swift3.0语言教程字符串与URL的数据转换 Swift3.0语言教程字符串与URL的数据转换与自由转换,字符串中的字符永久保存除了可以 ...

  8. 【转贴】 Flex 预编译处理 与 手机项目、Web项目、Air项目自由转换

    原文连接: http://bbs.9ria.com/forum.php?mod=viewthread&tid=263350#lastpost 由于这个论坛不稳定,所以转到这里来,这个帖子蛮有用 ...

  9. 简单使用AutoMapper实现DTO转换

    DTO(Data Transfer Object)数据传输对象,只是传输数据,完成与领域对象之间的转换,并不包含领域业务处理. 当领域模型设计人员只关注核心业务,满足于领域模型的精巧,而不关心具体实现 ...

随机推荐

  1. PAT B1033 旧键盘打字 (20 分)

    旧键盘上坏了几个键,于是在敲一段文字的时候,对应的字符就不会出现.现在给出应该输入的一段文字.以及坏掉的那些键,打出的结果文字会是怎样? 输入格式: 输入在 2 行中分别给出坏掉的那些键.以及应该输入 ...

  2. Python2.7-random

    random 模块,实现了各种分布下的伪随机数生成器.对于整数,可以从一个范围中随机挑选:对于序列,可以随机挑选其中的元素但不改变原序列,也可以对序列中的元素进行重新排列.此外,模块还封装了各种分布函 ...

  3. (四) DRF认证, 权限, 节流

    一.Token 认证的来龙去脉 摘要 Token 是在服务端产生的.如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回 Token 给前端.前端可以在每次请求的时候带上 To ...

  4. iscsi target tgt架构

    tgt是用户态实现的iscsi target,而iet(iscsi enterprise target)是在内核态实现的target,tgt相比于iet来说,因为其用户态实现,方便调试,新加入一些功能 ...

  5. HO引擎近况20190110

    前两天更新完,挺兴奋 趁着兴奋把虚拟机里面的MACOSX从10.12.6升级到了10.14 然后装XCODE,虽然比较熟悉了,但是架不住慢啊 先下载了一个DMG的镜像文件,用不了,转成ISO也不行 然 ...

  6. Tomcat 动态数据库连接池

    package com.boguan.bte.util; import java.sql.Connection;import java.sql.SQLException;import java.uti ...

  7. 20155310《网络对抗》Exp2 后门原理与实践

    20155310<网络对抗>Exp2 后门原理与实践 基础问题回答 1.例举你能想到的一个后门进入到你系统中的可能方式? 在网上下载软件的时候,后门很有可能被捆绑在下载的软件当中: 浏览网 ...

  8. 几种flash存储芯片的用途和分类

    1.IIC EEPROM------容量小,采用的是IIC通信协议:用于在掉电时,存系统配置参数,比如屏幕亮度等.常用芯片型号有 AT24C02.FM24C02.CAT24C02等,其常见的封装多为D ...

  9. Paxos算法浅析

    前言在文章2PC/3PC到底是啥中介绍了2PC这种一致性协议,从文中了解到2PC更多的被用在了状态一致性上(分布式事务),在数据一致性中很少被使用:而Paxos正是在数据一致性中被广泛使用,在过去十年 ...

  10. Security4:授予查看定义,执行SP和只读数据的权限

    SQL Server数据库有完善的权限管理机制,对于存储过程,其权限分为查看定义,执行和修改,查看SP定义的权限是:VIEW DEFINITION ,执行存储过程的权限是:EXECUTE,修改SP的权 ...