在上一篇文章中我们构造出了完整的应用场景,包括我们的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. P2731 骑马修栅栏 Riding the Fences

    题目描述 John是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经过一个栅栏.你必须编一个程序,读入栅栏网络的描述,并计算出一条修栅栏的路径,使每个栅栏都恰好被经过一次.John能从任何一个顶 ...

  2. shell杂记

    (本文将持续更新)从2015年9月25日开始正式学习linux类的东西. 书籍入门:UNIX.Shell编程24学时教程(中文版).Linux与UNIX Shell编程指南.shell十三问.LINU ...

  3. qmlscene: could not find a Qt installation of ''

    qt └── helloqt.qml 在qt目录下运行helloqt.qml文件时出现这个提示: $ qmlscene helloqt.qml qmlscene: could not find a Q ...

  4. 第18章 SysTick—系统定时器

    第18章     SysTick—系统定时器 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/ ...

  5. 2017-2018-2 20155233『网络对抗技术』Exp6:信息收集与漏洞扫描

    通过DNS和IP挖掘目标网站的信息 whois查询:用来进行域名注册信息查询,以得到3R注册信息,包括注册人的名字.组织.城市等信息.(进行whois查询时去掉www等前缀,因为注册域名时通常会注册一 ...

  6. 2017-2018-2 《网络对抗技术》20155322 Exp9 web安全基础

    [-= 博客目录 =-] 1-实践目标 1.1-实践介绍 1.2-实践内容 1.3-实践要求 2-实践过程 2.1-HTML 2.2-Injection Flaws 2.3-XSS 2.4-CSRF ...

  7. 20155331《网路对抗》Exp8 WEB基础实践

    20155331<网路对抗>Exp8 WEB基础实践 基础问题回答 什么是表单 表单在网页中主要负责数据采集功能.一个表单有三个基本组成部分: 表单标签,这里面包含了处理表单数据所用CGI ...

  8. WPF编程,指定窗口图标、窗口标题,使得在运行状态下任务栏显示窗口图标的一种方法。

    原文:WPF编程,指定窗口图标.窗口标题,使得在运行状态下任务栏显示窗口图标的一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_4330793 ...

  9. WinRT IO相关整理

    虽然一般UWP开发还是依赖.Net for UWP,但有时还是需要调用WinRT API.特别是在IO部分,WinRT有着和.Net似曾相识但又不尽相同的接口.在此对经常用到的一些地方进行一下整理. ...

  10. mfc 动态为控件添加事件1

    知识点: 认识窗口过程 GetWindowLong SetWindowLong 为动态控件绑定事件 一.获取窗口过程 二.设置新窗口过程 .书写一个新窗口过程函数 窗口过程格式 LRESULT CAL ...