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

    matplotlib的pyplot子库提供了和matlab类似的绘图API,方便用户快速绘制2D图表 一般用以下形式导入:import matplotlib.pyplot as plt 一般用法:1. ...

  2. Web.config中 mode="RemoteOnly" 跟mode="On" 区别

    转载网址:mode="RemoteOnly" 跟mode="On" 区别 <!-- 自定义错误信息 设置 customErrors mode=" ...

  3. 在 ASP.NET CORE 中使用 SESSION (转载)

    Session 是保存用户和 Web 应用的会话状态的一种方法,ASP.NET Core 提供了一个用于管理会话状态的中间件.在本文中我将会简单介绍一下 ASP.NET Core 中的 Session ...

  4. 【chrome】"您的连接不是私密连接" 解决办法

    1.启用显示证书选项 在Chrome的地址栏中输入:chrome://flags/#show-cert-link,选择"启用",重启Chrome浏览器.  (操作过无用) 2.安装 ...

  5. 你也可以自己写一个可爱 & 小资风格的Android加载等待自定义View - 转

    http://blog.csdn.net/carson_ho/article/details/77712072

  6. 如何取得Oracle并行执行的trace

    如何取得Oracle并行执行的trace: ALTER SESSION SET tracefile_identifier='10046_PROD';ALTER SESSION SET max_dump ...

  7. GBDT源码剖析

    如今,GBDT被广泛运用于互联网行业,他的原理与优点这里就不细说了,网上google一大把.但是,我自认为自己不是一个理论牛人,对GBDT的理论理解之后也做不到从理论举一反三得到更深入的结果.但是学习 ...

  8. 设计模式学习---UML常见关系的实现

    一.UML基本构造 UML的基本构造含3种: (1) 事物(4种):结构事物,行为事物,分组事物,注释事物 (2) 关系(4种):泛化关系,实现关系,依赖关系,关联关系 (3) 图(10种):用例图, ...

  9. QTP_随机生成N个字符(包含数字和字母)

    '************************************************************* ' Name: GetRandomString ' Purpose: 随机 ...

  10. python的闭包函数

    在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用.这样就构成了一个闭包. #闭包函数的实例# outer是外部函数 a和b都是外函数的临时变量def o ...