首页 后端开发 C#.Net教程 使用AutoMapper实现Dto和Model的自由转换(中)

使用AutoMapper实现Dto和Model的自由转换(中)

Dec 20, 2016 am 11:30 AM
c#

注:本系列文章的代码可以在这里下载。 

在上一篇文章中我们构造出了完整的应用场景,包括我们的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并传入要映射的类型): 

C#代码  

Mapper.CreateMap();  


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

C#代码  

AddressDto dto = new AddressDto  

{  

    Country = "China",  

    City = "Beijing",  

    Street = "Dongzhimen Street",  

    PostCode = "100001"  

};  

Address address = Mapper.Map(Dto);  

address.Country.ShouldEqual("China");  

address.City.ShouldEqual("Beijing");  

address.Street.ShouldEqual("Dongzhimen Street");  

address.PostCode.ShouldEqual("100001");  


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

C#代码  

Address address = Mapper.Map(new AddressDto  

                                                       {  

                                                           Country = "China"  

                                                       });  

address.City.ShouldBeNull();  

address.Street.ShouldBeNull();  

address.PostCode.ShouldBeNull();  


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

C#代码  

Address address = Mapper.Map(null);  

address.ShouldBeNull();  


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

C#代码  

IMappingExpression expression = Mapper.CreateMap();  

// Define mapping rules from BookDto to Book here  

Mapper.CreateMap();  

Mapper.CreateMap();  


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

C#代码  

BookStoreDto dto = new BookStoreDto  

                       {  

                           Name = "My Store",  

                           Address = new AddressDto  

                                         {  

                                             City = "Beijing"  

                                         },  

                           Books = new List  

                                       {  

                                           new BookDto {Title = "RESTful Web Service"},  

                                           new BookDto {Title = "Ruby for Rails"},  

                                       }  

                       };  

BookStore bookStore = Mapper.Map(dto);  

bookStore.Name.ShouldEqual("My Store");  

bookStore.Address.City.ShouldEqual("Beijing");  

bookStore.Books.Count.ShouldEqual(2);  

bookStore.Books.First().Title.ShouldEqual("RESTful Web Service");  

bookStore.Books.Last().Title.ShouldEqual("Ruby for Rails");  


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

C#代码  

var map = Mapper.CreateMap();  

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方式,我们可以: 

C#代码  

var map = Mapper.CreateMap();  

map.ConstructUsing(s => new ContactInfo  

                                          {  

                                              Blog = s.FirstAuthorBlog,  

                                              Email = s.FirstAuthorEmail,  

                                              Twitter = s.FirstAuthorTwitter  

                                          });  


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

C#代码  

BookDto dto = new BookDto  

                        {  

                            FirstAuthorEmail = "matt.rogen@abc.com",  

                            FirstAuthorBlog = "matt.amazon.com",  

                        };  

ContactInfo contactInfo = Mapper.Map(dto);  



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

C#代码  

var map = Mapper.CreateMap();  

map.ForMember(d => d.Country, opt => opt.MapFrom(s => s.CountryName));  


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


本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1659
14
CakePHP 教程
1415
52
Laravel 教程
1310
25
PHP教程
1258
29
C# 教程
1232
24
C# 序列化 C# 序列化 Sep 03, 2024 pm 03:30 PM

C# 序列化指南。这里我们分别讨论C#序列化对象的介绍、步骤、工作原理和示例。

使用 C# 的活动目录 使用 C# 的活动目录 Sep 03, 2024 pm 03:33 PM

使用 C# 的 Active Directory 指南。在这里,我们讨论 Active Directory 在 C# 中的介绍和工作原理以及语法和示例。

C# 中的随机数生成器 C# 中的随机数生成器 Sep 03, 2024 pm 03:34 PM

C# 随机数生成器指南。在这里,我们讨论随机数生成器的工作原理、伪随机数和安全数的概念。

C# 数据网格视图 C# 数据网格视图 Sep 03, 2024 pm 03:32 PM

C# 数据网格视图指南。在这里,我们讨论如何从 SQL 数据库或 Excel 文件加载和导出数据网格视图的示例。

c#多线程和异步的区别 c#多线程和异步的区别 Apr 03, 2025 pm 02:57 PM

多线程和异步的区别在于,多线程同时执行多个线程,而异步在不阻塞当前线程的情况下执行操作。多线程用于计算密集型任务,而异步用于用户交互操作。多线程的优势是提高计算性能,异步的优势是不阻塞 UI 线程。选择多线程还是异步取决于任务性质:计算密集型任务使用多线程,与外部资源交互且需要保持 UI 响应的任务使用异步。

C# 中的阶乘 C# 中的阶乘 Sep 03, 2024 pm 03:34 PM

C# 阶乘指南。这里我们讨论 C# 中阶乘的介绍以及不同的示例和代码实现。

C# 中的模式 C# 中的模式 Sep 03, 2024 pm 03:33 PM

C# 模式指南。在这里,我们讨论 C# 中模式的介绍和前 3 种类型,以及其示例和代码实现。

C# 中的质数 C# 中的质数 Sep 03, 2024 pm 03:35 PM

C# 素数指南。这里我们讨论c#中素数的介绍和示例以及代码实现。

See all articles