日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

【C#】使用AutoMapper-看这篇就够了

發(fā)布時間:2024/1/1 C# 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【C#】使用AutoMapper-看这篇就够了 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言
本文基于發(fā)稿時:

  • Automapper的最新版本:10.1.1。此擴展用于非ASP.NET Core程序。
  • AutoMapper.Extensions.Microsoft.DependencyInjection的最新版本:8.1.1。此擴展用于ASP.NET Core程序

瀏覽的時候比較重要內容我在標題前加了“★”, 可以重點關注。

文章目錄

  • 0. 快速開始
  • 1.常見配置
    • 1.1 Profile的配置
    • 1.2 兼容不同的命名方式 camelCase/PascalCase等
    • 1.3 映射時針對某些字符進行替換
    • 1.4 映射時匹配前綴或后綴
    • ★1.5控制哪些屬性和字段能夠被映射
    • 1.6 提前編譯
  • 2. Projection(映射)
    • ★2.1 手動控制某些成員的映射 `ForMember`+`MapFrom`
    • ★2.2 嵌套(`Nested`)類和繼承類映射
    • ★2.3 映射繼承與多態(tài) `Include/IncludeBase`
    • 2.4 構造函數(shù)映射
    • 2.5 復雜類映射成扁平類
    • ★2.6 映射反轉(Reverse Mapping)
    • 2.7 使用特性映射
    • 2.8 動態(tài)類型Dynamic到普通類型的映射
    • ★2.9 泛型映射
  • ★3. 擴展`IQueryable`(與EF等ORM配合使用)
    • 3.1 Expression Translation
    • 3.2 枚舉映射
  • 4.進階
    • ★4.1 類型轉換(可針對所有的maps生效)
    • 4.2 通過`MapFrom`自定義值解析(Value Resolve )
    • 4.3 映射時傳入數(shù)據
    • 4.4 條件映射 (`Conditions`和`Preconditions`)
    • 4.5 空值替換
    • 4.6 `ValueTransformers` 映射點綴(自己起的名字)
    • 4.7 映射前或映射后干點額外的事 `MapAction`
  • 5. AutoMapper的一些默認行為
  • 6.常見問題
    • 6.1 某一個功能用`ITypeConverter`、`IValueConverter`、`IValueResolver`、`IMemberValueResover`好像都可以實現(xiàn),我應該用哪個?
    • 6.2 什么時候需要手動調用`CreateMap

0. 快速開始

首先,配置映射關系

public class OrganizationProfile : Profile {public OrganizationProfile(){CreateMap<Foo, FooDto>();} }

如果是控制臺應用,則:

var configuration = new MapperConfiguration(cfg => {//cfg.CreateMap<Foo, Bar>();cfg.AddProfile<OrganizationProfile>();//或者cfg.AddProfile(new OrganizationProfile()); }); var mapper=configuration.CreateMapper();//或者var mapper=new Mapper(configuration);var dest=mapper.Map<OrderDto>(order);

如果ASP.NET Core應用,則(需安裝AutoMapper.Extensions.Microsoft.DependencyInjection):

//1. ConfigureServices里Add,入參類型為params services.AddAutoMapper(typeof(OrganizationProfile));//2. 然后在Controller里使用即可: public XXXController(IMapper mapper) {_mapper = mapper;var dest=mapper.Map<OrderDto>(order); }

1.常見配置

1.1 Profile的配置

除了上述的手動添加profile,還可以自動掃描profile并添加:

//方法1 var configuration = new MapperConfiguration(cfg => cfg.AddMaps(myAssembly));//方法2:通過程序集名 var configuration = new MapperConfiguration(cfg =>cfg.AddMaps(new [] {"Foo.UI","Foo.Core"}); );//方法3:通過typeof var configuration = new MapperConfiguration(cfg =>cfg.AddMaps(new [] {typeof(HomeController),typeof(Entity)}); );

1.2 兼容不同的命名方式 camelCase/PascalCase等

作用:駝峰命名與Pascal命名的兼容。

以下全局配置會映射property_name到PropertyName

var configuration = new MapperConfiguration(cfg => {cfg.SourceMemberNamingConvention = new LowerUnderscoreNamingConvention();cfg.DestinationMemberNamingConvention = new PascalCaseNamingConvention(); });

或者針對某個profile進行配置(這種方式全局通用):

public class OrganizationProfile : Profile {public OrganizationProfile(){SourceMemberNamingConvention = new LowerUnderscoreNamingConvention();DestinationMemberNamingConvention = new PascalCaseNamingConvention();//Put your CreateMap... Etc.. here} }

1.3 映射時針對某些字符進行替換

var configuration = new MapperConfiguration(c => {c.ReplaceMemberName("?", "A");c.ReplaceMemberName("í", "i");c.ReplaceMemberName("Airlina", "Airline"); });

進行以上配置之后,會自動將?bc映射到Abc上,將íng映射到ing上,將AirlinaMark映射到AirlineMark上。

1.4 映射時匹配前綴或后綴

var configuration = new MapperConfiguration(cfg => {cfg.RecognizePrefixes("frm");//cfg.RecongizePostfixes("后綴");cfg.CreateMap<Source, Dest>(); });

這樣frmValue就可以map到Value上。

Automapper默認匹配了Get前綴,如果不需要可以清除:

cfg.ClearPrefixes();//清除所有前綴

★1.5控制哪些屬性和字段能夠被映射

使用ShouldMapField和ShouldMapProperty

cfg.ShouldMapField = fi => false; cfg.ShouldMapProperty = pi =>pi.GetMethod != null && (pi.GetMethod.IsPublic || pi.GetMethod.IsPrivate);

默認所有public的field和property都會被map,也會map private 的setter,但是不會map整個property都是internal/private的屬性。

1.6 提前編譯

默認是調用的時候才編譯映射,但是可以要求AutoMapper提前編譯,但是可能會花費點時間:

var configuration = new MapperConfiguration(cfg => {}); configuration.CompileMappings();

2. Projection(映射)

AutoMapper只會映射扁平的類,所以嵌套的類,繼承的類,需要進行手動配置。成員名稱不一致時,也要手動配置映射。

AutoMapper默認會自動映射以下類型,并且映射時會先清空dest對應成員的數(shù)據:

  • IEnumerable
  • IEnumerable<T>
  • ICollection
  • ICollection<T>
  • IList
  • IList<T>
  • List<T>
  • Arrays

這幾個集合之間可以相互映射,如:mapper.Map<Source[], IEnumerable<Destination>>(sources);

★2.1 手動控制某些成員的映射 ForMember+MapFrom

// Configure AutoMapper var configuration = new MapperConfiguration(cfg =>cfg.CreateMap<CalendarEvent, CalendarEventForm>().ForMember(dest => dest.EventDate, opt => opt.MapFrom(src => src.Date.Date)).ForMember(dest => dest.EventHour, opt => opt.MapFrom(src => src.Date.Hour)).ForMember(dest => dest.EventMinute, opt => opt.MapFrom(src => src.Date.Minute)));

將src的Date.Date映射到dest的EventDate成員上

★2.2 嵌套(Nested)類和繼承類映射

某些成員可能是一個類,那么這個類也要配置映射。同理一個類的父類也要配置映射。

var config = new MapperConfiguration(cfg => {cfg.CreateMap<OuterSource, OuterDest>();cfg.CreateMap<InnerSource, InnerDest>(); });

★2.3 映射繼承與多態(tài) Include/IncludeBase

假如ChildSource繼承ParentSource,ChildDestination繼承ParentDestination。并且有這么一個業(yè)務,ParentSource src=new ChildSource()需要把src轉為ParentDestination。

直接轉的話肯定會有member丟失,所以要進行如下配置:

var configuration = new MapperConfiguration(c=> {c.CreateMap<ParentSource, ParentDestination>().Include<ChildSource, ChildDestination>();c.CreateMap<ChildSource, ChildDestination>(); });

或者也可以這么寫:

CreateMap<ParentSource,ParentDestination>(); CreateMap<ChildSource,ChildDestination>().IncludeBase<ParentSource,ParentDestination>();

如果有幾十個類都繼承了ParentSource和ParentDestination,那么上述兩種方法就太啰嗦了,可以這么寫:

CreateMap<ParentSource,ParentDestination>().IncludeAllDerived(); CreaetMap<ChildSource,ChildDestination>();

更復雜的用法參考:Mapping-inheritance

2.4 構造函數(shù)映射

如果dest構造函數(shù)的入參名和src的某個member一致,則不用手動配置,automapper會自動支持:

public int Value { get; set; } } public class SourceDto {public SourceDto(int value) {_value = value;}private int _value;public int Value {get { return _value; }} }

如果這里構造的入參不叫value而叫value2,則要進行如下配置:

var configuration = new MapperConfiguration(cfg =>cfg.CreateMap<Source, SourceDto>().ForCtorParam("value2", opt => opt.MapFrom(src => src.Value)) );

也可以禁用構造函數(shù)映射:
var configuration = new MapperConfiguration(cfg => cfg.DisableConstructorMapping());

也可以配置什么情況下不用構造函數(shù)映射:
var configuration = new MapperConfiguration(cfg => cfg.ShouldUseConstructor = ci => !ci.IsPrivate);//不匹配私有構造函數(shù)

2.5 復雜類映射成扁平類

public class Src {public Customer Customer {get;set;}public int GetTotal(){return 0;} } public class Customer {public string Name {get;set;} } public class Dest {public string CustomerName {get;set;}public int Total {get;set;} }

則src可以自動映射成dest,包括CustomerName和Total字段。這種與手動配置cfg.CreateMap<Src,Dest>().ForMember(d=>d.CustomerName,opt=>opt.MapFrom(src=>src.Customer.Name))然后進行映射的方式類似。

映射時AutoMapper發(fā)現(xiàn),src里沒有CustomerName這個成員,則會將dest的CustomerName按照PascalCase的命名方式拆分為獨立的單詞。所以CustomerName會映射到src的Customer.Name。如果想禁用這種自動映射,則調用cfg.DestinationMemberNamingConvention = new ExactMatchNamingConvention();使用精確映射。

如果感覺AutoMapper的這種基于PascalCase命名拆分的自動映射沒法滿足你的需要,則還可以手動指定某些成員的映射:

class Source {public string Name { get; set; }public InnerSource InnerSource { get; set; }public OtherInnerSource OtherInnerSource { get; set; } } class InnerSource {public string Name { get; set; }public string Description { get; set; } } class OtherInnerSource {public string Name { get; set; }public string Description { get; set; }public string Title { get; set; } } class Destination {public string Name { get; set; }public string Description { get; set; }public string Title { get; set; } }cfg.CreateMap<Source, Destination>().IncludeMembers(s=>s.InnerSource, s=>s.OtherInnerSource); cfg.CreateMap<InnerSource, Destination>(MemberList.None); cfg.CreateMap<OtherInnerSource, Destination>();var source = new Source { Name = "name", InnerSource = new InnerSource{ Description = "description" }, OtherInnerSource = new OtherInnerSource{ Title = "title",Description="descpripiton2" } }; var destination = mapper.Map<Destination>(source); destination.Name.ShouldBe("name"); destination.Description.ShouldBe("description"); destination.Title.ShouldBe("title");

IncludeMembers參數(shù)的順序很重要,這也就是dest的Description為“description”而不是“description2”的原因,因為InnerSource的Description屬性最先匹配到了Destination的Description屬性。

IncludeMembers相當于把子類打平添加到了src里,并進行映射。

★2.6 映射反轉(Reverse Mapping)

reverse mapping一般在CreateMap方法或者ForMember等方法之后,相當于src和dest根據你自己的配置可以相互映射,少寫一行代碼:

cfg.CreateMap<Order, OrderDto>().ReverseMap(); //等同于以下兩句 cfg.CreateMap<Order,OrderDto>(); cfg.CreateMap<OrderDto,Order>();

如果還想對reverse map進行自定義(大多數(shù)情況下都不需要),則可以使用ForPath:

cfg.CreateMap<Order, OrderDto>().ForMember(d => d.CustomerName, opt => opt.MapFrom(src => src.Customer.Name)).ReverseMap().ForPath(s => s.Customer.Name, opt => opt.MapFrom(src => src.CustomerName));

注意:
如果reverse之前定義了一些諸如ForMember之類的約束,這些約束是不會自動reverse的,需要手動配置。以下代碼配置了不管從Order映射到OrderDto還是從OrderDto映射到Order,都忽略CustomerName屬性。

cfg.CreateMap<Order, OrderDto>().ForMember(d => d.CustomerName, opt => opt.Ignore()).ReverseMap().ForMember(d => d.CustomerName, opt => opt.Ignore())

2.7 使用特性映射

(C#稱作特性,Java叫注解)

[AutoMap(typeof(Order))] public class OrderDto {}

等同于CreateMap<Order,OrderDto>()。然后配置的時候用AddMaps方法:

var configuration = new MapperConfiguration(cfg => cfg.AddMaps("MyAssembly")); var mapper = new Mapper(configuration);

注解里還有如下參數(shù)供設置:

  • ReverseMap (bool)
  • ConstructUsingServiceLocator (bool)
  • MaxDepth (int)
  • PreserveReferences (bool)
  • DisableCtorValidation (bool)
  • IncludeAllDerived (bool)
  • TypeConverter (Type)

映射注解的更多信息參考:Attribute-mapping

2.8 動態(tài)類型Dynamic到普通類型的映射

默認就支持,不用手動CreateMap

★2.9 泛型映射

public class Source<T> {} public class Destination<T> {} var configuration = new MapperConfiguration(cfg => cfg.CreateMap(typeof(Source<>), typeof(Destination<>)));

注意:CreateMap不需要傳具體的T

★3. 擴展IQueryable(與EF等ORM配合使用)

需要安裝nuget包:AutoMapper.EF6

這個功能存在的意義是為了解決一些orm框架返回的是IQueryable類型,使用一般的mapper.Map做轉換時,會查詢出來整行數(shù)據,然后再挑選出來某些字段做映射,會降低性能的問題。解決方法是使用ProjectTo:

public class OrderLine {public int Id { get; set; }public int OrderId { get; set; }public Item Item { get; set; }public decimal Quantity { get; set; } } public class Item {public int Id { get; set; }public string Name { get; set; } } public class OrderLineDTO {public int Id { get; set; }public int OrderId { get; set; }public string Item { get; set; }public decimal Quantity { get; set; } }var configuration = new MapperConfiguration(cfg =>cfg.CreateMap<OrderLine, OrderLineDTO>().ForMember(dto => dto.Item, conf => conf.MapFrom(ol => ol.Item.Name)));public List<OrderLineDTO> GetLinesForOrder(int orderId) {using (var context = new orderEntities()){return context.OrderLines.Where(ol => ol.OrderId == orderId).ProjectTo<OrderLineDTO>(configuration).ToList();} } //這樣查Item表的時候,只會select name字段。

3.1 Expression Translation

TBD

3.2 枚舉映射

大多數(shù)情況下都不需要進行此項的配置。考慮以下兩個枚舉:

public enum Source {Default = 0,First = 1,Second = 2 }public enum Destination {Default = 0,Second = 2 }

如果想把Source.First映射到Destination.Default上,則需要安裝AutoMapper.Extensions.EnumMapping nuget包,然后進行如下配置:

internal class YourProfile : Profile {public YourProfile(){CreateMap<Source, Destination>().ConvertUsingEnumMapping(opt => opt// optional: .MapByValue() or MapByName(), without configuration MapByValue is used.MapValue(Source.First, Destination.Default)).ReverseMap(); } }

默認情況下AutoMapper.Extensions.EnumMapping 會將源枚舉里所有的數(shù)據根據枚舉值或枚舉名稱映射到目標枚舉上。如果找不到且啟用了EnumMappingValidation,則會拋出異常。

4.進階

★4.1 類型轉換(可針對所有的maps生效)

當從可空類型與不可空類型相互轉換時,當string與int等轉換時,就需要自定義類型轉換。一般有以下三種方法:

void ConvertUsing(Func<TSource, TDestination> mappingFunction); void ConvertUsing(ITypeConverter<TSource, TDestination> converter); void ConvertUsing<TTypeConverter>() where TTypeConverter : ITypeConverter<TSource, TDestination>;

簡單情景下使用第一種,復雜情景下自定義類去實現(xiàn)ITypeConverter接口。綜合舉例如下:

public class Source {public string Value1 { get; set; }public string Value2 { get; set; }public string Value3 { get; set; } } public class Destination {public int Value1 { get; set; }public DateTime Value2 { get; set; }public Type Value3 { get; set; } } public void Example() {var configuration = new MapperConfiguration(cfg => {cfg.CreateMap<string, int>().ConvertUsing(s => Convert.ToInt32(s));cfg.CreateMap<string, DateTime>().ConvertUsing(new DateTimeTypeConverter());cfg.CreateMap<string, Type>().ConvertUsing<TypeTypeConverter>();cfg.CreateMap<Source, Destination>();});configuration.AssertConfigurationIsValid();var source = new Source{Value1 = "5",Value2 = "01/01/2000",Value3 = "AutoMapperSamples.GlobalTypeConverters.GlobalTypeConverters+Destination"};Destination result = mapper.Map<Source, Destination>(source);result.Value3.ShouldEqual(typeof(Destination)); }public class DateTimeTypeConverter : ITypeConverter<string, DateTime> {public DateTime Convert(string source, DateTime destination, ResolutionContext context){return System.Convert.ToDateTime(source);} }public class TypeTypeConverter : ITypeConverter<string, Type> {public Type Convert(string source, Type destination, ResolutionContext context){return Assembly.GetExecutingAssembly().GetType(source);} }

4.2 通過MapFrom自定義值解析(Value Resolve )

針對的是某一個map的某一個member,有3種寫法:

  • MapFrom<TValueResolver>
  • MapFrom(typeof(CustomValueResolver))
  • MapFrom(new CustomResolver())
public class Source {public int Value1 { get; set; }public int Value2 { get; set; } } public class Destination {public int Total { get; set; } } public class CustomResolver : IValueResolver<Source, Destination, int> {public int Resolve(Source source, Destination destination, int member, ResolutionContext context){//可以添加其他邏輯return source.Value1 + source.Value2;} } var configuration = new MapperConfiguration(cfg =>cfg.CreateMap<Source, Destination>().ForMember(dest => dest.Total, opt => opt.MapFrom<CustomResolver>())); configuration.AssertConfigurationIsValid();var source = new Source{Value1 = 5,Value2 = 7};var result = mapper.Map<Source, Destination>(source); result.Total.ShouldEqual(12);

這種與一般的MapFrom(src=>src.Value1+src.Value2)區(qū)別是可以添加更加復雜的邏輯。

如果想要一個更通用的CustomResolver,不管src和dest是什么類型的都能用,則可以實現(xiàn)IValueResolver<object,object,int>接口。但是這個resolver里沒法獲取dest的value,如果有這種需要的話,可以實現(xiàn)ImemberValueResolver接口,進行更細粒度的控制。

4.3 映射時傳入數(shù)據

只支持傳入鍵值對格式的數(shù)據

cfg.CreateMap<Source, Dest>().ForMember(dest => dest.Foo, opt => opt.MapFrom((src, dest, destMember, context) => context.Items["Foo"])); mapper.Map<Source, Dest>(src, opt => opt.Items["Foo"] = "Bar");

4.4 條件映射 (Conditions和Preconditions)

符合某些條件時才映射

var configuration = new MapperConfiguration(cfg => {cfg.CreateMap<Foo,Bar>().ForMember(dest => dest.baz, opt => opt.Condition(src => (src.baz >= 0))); }); var configuration = new MapperConfiguration(cfg => {cfg.CreateMap<Foo,Bar>().ForMember(dest => dest.baz, opt => {opt.PreCondition(src => (src.baz >= 0));opt.MapFrom(src => {//有了Precondition,這里的操作有可能不執(zhí)行,節(jié)省資源});}); });

Condition()方法會在MapFrom方法后執(zhí)行,而Preconditions會在MapFrom前執(zhí)行

4.5 空值替換

作用:如果src為null的話,就給dest一個默認值

var config = new MapperConfiguration(cfg => cfg.CreateMap<Source, Dest>().ForMember(destination => destination.Value, opt => opt.NullSubstitute("Other Value"))); var source = new Source { Value = null }; var mapper = config.CreateMapper(); var dest = mapper.Map<Source, Dest>(source);dest.Value.ShouldEqual("Other Value");source.Value = "Not null"; dest = mapper.Map<Source, Dest>(source); dest.Value.ShouldEqual("Not null");

4.6 ValueTransformers 映射點綴(自己起的名字)

作用:在賦值的時候,我想額外在值上加點東西

var configuration = new MapperConfiguration(cfg => {cfg.ValueTransformers.Add<string>(val => val + "!!!"); });var source = new Source { Value = "Hello" }; var dest = mapper.Map<Dest>(source);dest.Value.ShouldBe("Hello!!!");

可以應用到全局、某個Profile、某個Map或某個member。

4.7 映射前或映射后干點額外的事 MapAction

可以提前配置:

var configuration = new MapperConfiguration(cfg => {cfg.CreateMap<Source, Dest>().BeforeMap((src, dest) => src.Value = src.Value + 10).AfterMap((src, dest) => dest.Name = "John"); });

也可以在map時進行配置:

int i = 10; mapper.Map<Source, Dest>(src, opt => {opt.BeforeMap((src, dest) => src.Value = src.Value + i);opt.AfterMap((src, dest) => dest.Name = HttpContext.Current.Identity.Name); });

MapAction也可以創(chuàng)建全局的。

詳細用法:Before-and-after-map-actions

5. AutoMapper的一些默認行為

  • 當映射集合時,如果src的成員為null,則dest的成員會new一個默認值,而不是直接復制為null。如果真要映映射為null,則如下修改:
  • var configuration = new MapperConfiguration(cfg => {cfg.AllowNullCollections = true;cfg.CreateMap<Source, Destination>(); });

    這個功能可以配置成全局的、某個profile的或某個member的。

  • CreateMap<SRC,DEST>,創(chuàng)建映射時前后書寫順序不重要。
  • 映射集合時,會把dest的數(shù)據給清除掉,如果不想要這么做,參考github項目AutoMapper.Collection。
  • 假如某個成員的名稱為NameAAA,則名為NameAAA的field,與名為NameAAA的property,與名為GetNameAAA的方法,三者之間可以自動相互映射。
  • 類型轉換:AutoMapper支持.NET Framework自帶的一些基本的類型轉換。所以當src的member是非string類型,dest的是string類型時,映射的時候AutoMapper會調用ToString方法。對于那些不支持的類型轉換,需要自己定義Type Converter。
  • 6.常見問題

    6.1 某一個功能用ITypeConverter、IValueConverter、IValueResolver、IMemberValueResover好像都可以實現(xiàn),我應該用哪個?

    這幾個的釋義如下:

    • Type converter = Func<TSource, TDestination, TDestination>
    • Value resolver = Func<TSource, TDestination, TDestinationMember>
    • Member value resolver = Func<TSource, TDestination, TSourceMember, TDestinationMember>
    • Value converter = Func<TSourceMember, TDestinationMember>

    這四個的使用方式都是使用ConvertUsing()方法,區(qū)別是type converter 是針對全局的,其它三個是針對某個member的。 入參出參也不一樣。

    6.2 什么時候需要手動調用CreateMap<Src,Dest>()?

    雖然AutoMapper的官方文檔,一直都寫著在映射之前要先用CreateMap方法進行配置。但在實際使用過程中,我發(fā)現(xiàn)并不是任何時候都需要先配置才能用。

    假如dest里的每一個member(屬性、字段、Get方法)都能在src里找得到,則不需要額外的配置,即下屬代碼也可以正常運行:

    class Person {public string Name { get; set; }public int Age { get; set; } } class Person2 {public string Name { get; set; }public int? Age { get; set; }public DateTime BirthTime { get; set; } } public class NormalProfile : Profile {public NormalProfile(){//CreateMap<Person2, Person>();//} }var cfg = new MapperConfiguration(c => { c.AddProfile<NormalProfile>(); }); //cfg.AssertConfigurationIsValid(); var mapper = cfg.CreateMapper(); var s3 = mapper.Map<Person>(new Person2 { Name = "Person2" });

    6.3 ReverseMap到底能Reverse哪些東西?

  • 可以Reverse像PascalCase的命名方式拆分的member,就像CreateMap可以自動處理Customer.Name與CustomerName的映射一樣。即:CreateMap不需要額外配置正向就能映射的,那 ReverseMap也可以自動反向映射。
  • opt.MapForm()操作可以被reverse,如CreateMap<Person2, Person>().ForMember(dest => dest.Name2, opt => opt.MapFrom(src => src.Name)).ReverseMap();,當從Person映射到Person2的時候,Name2也可以直接映射到Name上。
  • 不支持opt.Ignore()反向映射,即CreateMap<Person2, Person>().ForMember(dest => dest.Name, opt => opt.Ignore()).ReverseMap()支持Person2->Person時,忽略Name屬性,但是從Person->Person2時,不會忽略,如果要忽略的話,還需要再加上.ForMember(dest => dest.Name, opt => opt.Ignore())。
  • 6.4 映射時如何跳過某些成員?

  • 使用CreateMap<src,dest>().ForMember(dest=>dest.AAA,opt=>opt.Ignore()),跳過成員AAA的映射。
  • 使用ShouldMapField委托跳過某些字段,使用ShouldMapProperty委托跳過某些屬性。
  • public class NormalProfile : Profile {public NormalProfile(){ShouldMapField = fi => false;CreateMap<Person2, Person>().ReverseMap();} } 或者 var cfg = new MapperConfiguration(c => { c.AddProfile<XXXXProfile>();c.ShouldMapField = fi => false; });

    總結

    以上是生活随笔為你收集整理的【C#】使用AutoMapper-看这篇就够了的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。