在上一篇文章中我们构造出了完整的应用场景,包括我们的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. jpbm工作流框架

    一:JBPM是什么?有什么用?能解决什么问题? 现实生活中有很多需要走一些流程的过程,比如请假流程,报销流程等,使用工作流框架,即可写一个流程即可,添加流程时不在繁琐的建立新的各种配置. 1:jBPM ...

  2. Java转python第一天

    1.python xx.py 2.字符串可以与数字相乘 str = "abc" msg = str*3 print(msg) # 结果:abcabcabc 3.换行用三个单引号 ' ...

  3. FakeID签名漏洞分析及利用(一)

    作者:申迪   转载请注明出处: http://blogs.360.cn/360mobile BlueBox于7月30日宣布安卓从2010年以来一直存在一个apk签名问题[1],并且会在今年Black ...

  4. 20155302《网络对抗》Exp6 信息收集与漏洞扫描

    20155302<网络对抗>Exp6 信息收集与漏洞扫描 实验内容 (1)各种搜索技巧的应用 (2)DNS IP注册信息的查询 (3)基本的扫描技术:主机发现.端口扫描.OS及服务版本探测 ...

  5. R语言学习 第四篇:函数和流程控制

    变量用于临时存储数据,而函数用于操作数据,实现代码的重复使用.在R中,函数只是另一种数据类型的变量,可以被分配,操作,甚至把函数作为参数传递给其他函数.分支控制和循环控制,和通用编程语言的风格很相似, ...

  6. JVM技术周报第1期

    JVM技术周报 · 第1期 JVM技术每周分享整理了JVM技术交流群每周讨论的内容,由群内成员整理归纳而成.如果你有兴趣入群讨论,请关注「Java技术精选」公众号,通过右下角菜单「入群交流」加我好友, ...

  7. golang高性能端口扫描

    前言 最近有个小项目的需要,使用golang写了个端口扫描工具,不得不说golang的效率确实比python快的太多了.在使用一段时间golang之后,感觉有三个方面是优于python的: 一个方面是 ...

  8. 《Effective Java》学习笔记 —— 通用程序设计

    本章主要讨论局部变量.控制结构.类库.反射.本地方法的用法及代码优化和命名惯例. 第45条 将局部变量的作用域最小化 * 在第一次使用的它的地方声明局部变量(就近原则). * 几乎每个局部变量的声明都 ...

  9. JQ_五星级评分特效

    代码如下:<!DOCTYPE HTML><html><head><meta http-equiv="Content-Type" conte ...

  10. Zip伪加密 破解ZIP密码

    ZIP是一种相当简单的分别压缩每个文件的存档格式.分别压缩文件允许不必读取另外的数据而检索独立的文件:理论上,这种格式允许对不同的文件使用不同的算法.不管用何种方法,对这种格式的一个告诫是对于包含很多 ...