当前位置 : 主页 > 网络编程 > 其它编程 >

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

来源:互联网 收集:自由互联 发布时间:2023-07-02
篇首语:本文由编程笔记#自由互联小编为大家整理,主要介绍了使用AutoMapper实现Dto和Model的自由转换(中)相关的知识,希望对你有一定的参考价值。在上一篇文章中我们构 篇首语:本
篇首语:本文由编程笔记#自由互联小编为大家整理,主要介绍了使用AutoMapper实现Dto和Model的自由转换(中)相关的知识,希望对你有一定的参考价值。在上一篇文章中我们构

篇首语:本文由编程笔记#自由互联小编为大家整理,主要介绍了使用AutoMapper实现Dto和Model的自由转换(中)相关的知识,希望对你有一定的参考价值。

在上一篇文章中我们构造出了完整的应用场景,包括我们的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#代码技术分享
  • AddressDtodto=newAddressDto
  • {
  • Country="China",
  • City="Beijing",
  • Street="DongzhimenStreet",
  • PostCode="100001"
  • };
  • Addressaddress=Mapper.Map(Dto);
  • address.Country.ShouldEqual("China");
  • address.City.ShouldEqual("Beijing");
  • address.Street.ShouldEqual("DongzhimenStreet");
  • address.PostCode.ShouldEqual("100001");
  • 如果AddressDto中有值为空的属性,AutoMapper在映射的时候会把Address中的相应属性也置为空:

    C#代码技术分享
  • Addressaddress=Mapper.Map(newAddressDto
  • {
  • Country="China"
  • });
  • address.City.ShouldBeNull();
  • address.Street.ShouldBeNull();
  • address.PostCode.ShouldBeNull();
  • 甚至如果传入一个空的AddressDto,AutoMapper也会帮我们得到一个空的Address对象。

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

    C#代码技术分享
  • IMappingExpressionexpression=Mapper.CreateMap();
  • //DefinemappingrulesfromBookDtotoBookhere
  • Mapper.CreateMap();
  • Mapper.CreateMap();
  • 然后我们就可以直接转换BookStoreDto了:

    C#代码技术分享
  • BookStoreDtodto=newBookStoreDto
  • {
  • Name="MyStore",
  • Address=newAddressDto
  • {
  • City="Beijing"
  • },
  • Books=newList
  • {
  • newBookDto{Title="RESTfulWebService"},
  • newBookDto{Title="RubyforRails"},
  • }
  • };
  • BookStorebookStore=Mapper.Map(dto);
  • bookStore.Name.ShouldEqual("MyStore");
  • bookStore.Address.City.ShouldEqual("Beijing");
  • bookStore.Books.Count.ShouldEqual(2);
  • bookStore.Books.First().Title.ShouldEqual("RESTfulWebService");
  • bookStore.Books.Last().Title.ShouldEqual("RubyforRails");
  • 【三】定义类型间的简单映射规则前面我们看了Convention的映射方式,客观的说还是有很多类型间的映射是无法通过简单的Convention方式来做的,这时候就需要我们使用Configuration了。好在我们的Configuration是在代码中以“强类型”的方式来写的,比写繁琐易错的xml方式是要好的多了。先来看看BookDto到Publisher的映射。回顾一下前文中定义的规则:BookDto.Publisher -> Publisher.Name。在AutoMapperzhong,我们可以这样映射:

    C#代码技术分享
  • varmap=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#代码技术分享
  • varmap=Mapper.CreateMap();
  • map.ConstructUsing(s=>newContactInfo
  • {
  • Blog=s.FirstAuthorBlog,
  • Email=s.FirstAuthorEmail,
  • Twitter=s.FirstAuthorTwitter
  • });
  • 然后,就可以按照我们熟悉的方式来使用了:

    C#代码技术分享
  • BookDtodto=newBookDto
  • {
  • FirstAuthorEmail="[emailprotected]",
  • FirstAuthorBlog="matt.amazon.com",
  • };
  • ContactInfocontactInfo=Mapper.Map(dto);
  • 如果需要映射的2个类型有部分字段名称相同,又有部分字段名称不同呢?还好AutoMapper给我们提供的Convention或Configuration方式并不是“异或的”,我们可以结合使用两种方式,为名称不同的字段配置映射规则,而对于名称相同的字段则忽略配置。例如对于前面提到的AddressDto到Address的映射,假如AddressDto的字段Country不叫Country叫CountryName,那么在写AddressDto到Address的映射规则时,只需要:

    C#代码技术分享
  • varmap=Mapper.CreateMap();
  • map.ForMember(d=>d.Country,opt=>opt.MapFrom(s=>s.CountryName));
  • 对于City、Street和PostCode无需定义任何规则,AutoMapper仍然可以帮我们进行正确的映射。

    网友评论