国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

【AutoMapper官方文檔】DTO與Domin Model相互轉(zhuǎn)換(上)

2019-11-17 03:11:45
字體:
供稿:網(wǎng)友

【AutoMapper官方文檔】DTO與Domin Model相互轉(zhuǎn)換(上)

寫在前面

  AutoMapper目錄:

  • 【AutoMapper官方文檔】DTO與Domin Model相互轉(zhuǎn)換(上)
  • 【AutoMapper官方文檔】DTO與Domin Model相互轉(zhuǎn)換(中)
  • 【AutoMapper官方文檔】DTO與Domin Model相互轉(zhuǎn)換(下)
  • 未完待續(xù)。。。

  本篇目錄:

  • Flattening-復(fù)雜到簡單

  • PRojection-簡單到復(fù)雜

  • Configuration Validation-配置驗(yàn)證

  • Lists and Array-集合和數(shù)組

  • Nested mappings-嵌套映射

  • 后記

  上一篇《【道德經(jīng)】漫談實(shí)體、對象、DTO及AutoMapper的使用》,因?yàn)閮?nèi)容寫的有點(diǎn)跑偏,關(guān)于AutoMapper的使用最后只是簡單寫了下,很明顯這種簡單的使用方式不能滿足項(xiàng)目中復(fù)雜的需要,網(wǎng)上找了下AutoMapper相關(guān)文檔,但差不多都是像我一樣簡單的概述下,看來懶的不只有我一個,哈哈。在AutoMapper 官方文檔中找到其使用的詳細(xì)說明,天書一樣的英文,然后就找相關(guān)中文文檔,最后還是沒找到,這邊沒辦法,只能自己動手,豐衣足食了。英語牛逼的可以直接略過,查看英文文檔,本篇也不算是翻譯,因?yàn)楸救擞⒄Z實(shí)在拿不出手,只是按照示例加上自己的一些理解,做個學(xué)習(xí)筆記,不對的地方還請指正。

  注:雖然上一篇寫跑偏了,但是本人真的很喜歡道德經(jīng),除了為人處世,在軟件設(shè)計(jì)這方面其實(shí)也有體現(xiàn),也希望可以運(yùn)用到這上面,如果你和我有一樣的想法,請?jiān)邳c(diǎn)擊公告欄中的QQ鏈接,知音難覓啊!

Flattening-復(fù)雜到簡單

  Flattening 翻譯為壓扁、拉平、扁平化的意思,可以理解為使原有復(fù)雜的結(jié)構(gòu)變得簡化,我們先看下領(lǐng)域模型和DTO代碼:

 1     public class Order 2     { 3         private readonly IList<OrderLineItem> _orderLineItems = new List<OrderLineItem>(); 4         public Customer Customer { get; set; } 5         public OrderLineItem[] GetOrderLineItems() 6         { 7             return _orderLineItems.ToArray(); 8         } 9         public void AddOrderLineItem(Product product, int quantity)10         {11             _orderLineItems.Add(new OrderLineItem(product, quantity));12         }13         public decimal GetTotal()14         {15             return _orderLineItems.Sum(li => li.GetTotal());16         }17     }18 19     public class Product20     {21         public decimal Price { get; set; }22         public string Name { get; set; }23     }24 25     public class OrderLineItem26     {27         public OrderLineItem(Product product, int quantity)28         {29             Product = product;30             Quantity = quantity;31         }32         public Product Product { get; private set; }33         public int Quantity { get; private set; }34         public decimal GetTotal()35         {36             return Quantity * Product.Price;37         }38     }39 40     public class Customer41     {42         public string Name { get; set; }43     }44 45     public class OrderDto46     {47         public string CustomerName { get; set; }48         public decimal Total { get; set; }49     }

  可以看到領(lǐng)域模型 Order 是很復(fù)雜的,但是對于業(yè)務(wù)場景中的OrderDto卻很簡單,只有 CustomerName和Total兩個屬性,AutoMapper配置代碼:

 1         public void Example() 2         { 3             var customer = new Customer 4             { 5                 Name = "George Costanza" 6             }; 7             var order = new Order 8             { 9                 Customer = customer10             };11             var bosco = new Product12             {13                 Name = "Bosco",14                 Price = 4.99m15             };16             order.AddOrderLineItem(bosco, 15);17             // 配置 AutoMapper18             Mapper.CreateMap<Order, OrderDto>();19             // 執(zhí)行 mapping20             OrderDto dto = Mapper.Map<Order, OrderDto>(order);21             Console.WriteLine("CustomerName:" + dto.CustomerName);22             Console.WriteLine("Total:" + dto.Total);23         }

  轉(zhuǎn)換效果:

  可以看到配置相當(dāng)?shù)暮唵危灰O(shè)置下Order和OrderDto之間的類型映射就可以了,我們看OrderDto中的CustomerName和Total屬性在領(lǐng)域模型Order中并沒有與之相對性,沒什么可以轉(zhuǎn)換呢,感覺好神奇的樣子,其實(shí)仔細(xì)發(fā)現(xiàn)這些屬性的命名都有一定的規(guī)則,AutoMapper在做解析的時候會按照PascalCase(帕斯卡命名法),就是一種變量命名法,除了PascalCase還有Hungarian(匈牙利命名法)和camelCase(駱駝命名法),PascalCase就是指混合使用大小寫字母來構(gòu)成變量和函數(shù)的名字,首字母要大寫,camelCase首字母小寫,我們C#命名中,一般使用的是camelCase和PascalCase,比較高級的是PascalCase。

  但是為什么AutoMapper會解析Total呢?因?yàn)樵陬I(lǐng)域模型Order中有個GetTotal()方法,AutoMapper會解析“Get”之后的單詞,所以會與Total相對應(yīng),如果你把OrderDto的屬性“Total”改為“Totals”,就會發(fā)現(xiàn)得到的“Totals”為0。理解了AutoMapper的解析方式,我們就要注意在編寫變量、屬性或是方法名稱的時候一定要規(guī)范,這也是一種好的習(xí)慣。

Projection-簡單到復(fù)雜

  Projection 翻譯為投影,F(xiàn)lattening是由復(fù)雜結(jié)構(gòu)簡化,Projection正好相反,投影可以理解為由原始結(jié)構(gòu)千變?nèi)f化,我們看下兩種轉(zhuǎn)換結(jié)構(gòu):

 1     public class CalendarEvent 2     { 3         public DateTime EventDate { get; set; } 4         public string Title { get; set; } 5     } 6  7     public class CalendarEventForm 8     { 9         public DateTime EventDate { get; set; }10         public int EventHour { get; set; }11         public int EventMinute { get; set; }12         public string Title { get; set; }13     }

  CalendarEvent是原始結(jié)構(gòu),CalendarEventForm是我們需要轉(zhuǎn)換后的結(jié)構(gòu),可以看到CalendarEventForm要比CalendarEvent結(jié)構(gòu)復(fù)雜些,看下AutoMapper配置轉(zhuǎn)換代碼:

 1         public void Example() 2         { 3             var calendarEvent = new CalendarEvent 4             { 5                 EventDate = new DateTime(2008, 12, 15, 20, 30, 0), 6                 Title = "Company Holiday Party" 7             }; 8  9             // 配置 AutoMapper10             Mapper.CreateMap<CalendarEvent, CalendarEventForm>()11                 .ForMember(dest => dest.EventDate, opt => opt.MapFrom(src => src.EventDate.Date))//定義映射規(guī)則12                 .ForMember(dest => dest.EventHour, opt => opt.MapFrom(src => src.EventDate.Hour))//定義映射規(guī)則13                 .ForMember(dest => dest.EventMinute, opt => opt.MapFrom(src => src.EventDate.Minute));//定義映射規(guī)則14 15             // 執(zhí)行 mapping16             CalendarEventForm form = Mapper.Map<CalendarEvent, CalendarEventForm>(calendarEvent);17 18             Console.WriteLine("EventDate:"+form.EventDate);19             Console.WriteLine("EventHour:" + form.EventHour);20             Console.WriteLine("EventMinute:" + form.EventMinute);21             Console.WriteLine("Title:" + form.Title);22         }

  和Flattening不同的是,我們除了定義類型映射,還要自定義映射規(guī)則,src.EventDate.Date指向dest.EventDate,src.EventDate.Minute指向dest.EventMinute,src.EventDate.Hour指向dest.EventHour,當(dāng)然我們還可以在MapFrom方法中做一些復(fù)雜的映射關(guān)系操作,MapFrom接受一個lambda表達(dá)式作為參數(shù),可以是任何的Func表達(dá)式。Projection適用于由簡單到復(fù)雜的結(jié)構(gòu)映射,一般體現(xiàn)在業(yè)務(wù)場景很復(fù)雜的情況下。

  【更正:Projection也不一定適用在由簡單到復(fù)雜的場景,應(yīng)該說使用Projection就是把AutoMapper的映射配置交給用戶來操作】

Configuration Validation-配置驗(yàn)證

  我們在使用Flattening的前提是我們需要轉(zhuǎn)換的結(jié)構(gòu)命名是沒有錯誤的,但是如果我們沒有使用PascalCase命名法,或者說我們命名是錯誤的,該怎么辦呢?比如下面代碼:

1         public class Source2         {3             public int SomeValue { get; set; }4         }5 6         public class Destination7         {8             public int SomeValuefff { get; set; }9         }

  可以看到Source和Destination中的字段并不相對應(yīng),我們測試下AutoMapper映射:

  AssertConfigurationIsValid方法是驗(yàn)證結(jié)構(gòu)映射的,如果配置不正確,會報“AutoMapperConfigurationException”異常錯誤,如何解決這個問題?你可能會說,就不能改下SomeValuefff的名稱嗎?這種方法可以,但是如果業(yè)務(wù)場景中必須要使用怎么辦呢,看了上面Projection的映射配置,你可能想到解決方法了,如下:

1             Mapper.CreateMap<Source, Destination>()2                 .ForMember(dest => dest.SomeValuefff, opt => opt.MapFrom(src => src.SomeValue));

  名稱不對,我們可以自定義映射規(guī)則,雖然這種方式可以,但是如果業(yè)務(wù)場景中SomeValuefff并不需要,那我們改怎么辦?既然有問題,就有解決之道,AutoMapper提供了Ignore方法,忽略不需要映射的數(shù)據(jù)結(jié)構(gòu),我們這樣配置就可以了:

1             Mapper.CreateMap<Source, Destination>()2                 .ForMember(dest => dest.SomeValuefff, opt => opt.Ignore());

Lists and Array-集合和數(shù)組

  有時候我們除了類型映射之外,還需要對集合類型進(jìn)行映射,先看個示例:

 1             public void Example() 2             { 3                 var sources = new[] 4                     { 5                         new Source {Value = 5}, 6                         new Source {Value = 6}, 7                         new Source {Value = 7} 8                     }; 9                 //配置AutoMapper10                 Mapper.Initialize(cfg =>11                 {12                     cfg.CreateMap<Source, Destination>();13                 });14                 //配置和執(zhí)行映射15                 IEnumerable<Destination> ienumerableDest = Mapper.Map<Source[], IEnumerable<Destination>>(sources);16                 ICollection<Destination> icollectionDest = Mapper.Map<Source[], ICollection<Destination>>(sources);17                 ILis
發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 页游| 华池县| 黄平县| 三明市| 增城市| 宜州市| 齐齐哈尔市| 谢通门县| 德安县| 军事| 灌阳县| 镇江市| 枣阳市| 巴塘县| 银川市| 华容县| 醴陵市| 凤冈县| 马关县| 普定县| 进贤县| 海城市| 阜新| 全州县| 长治市| 贺兰县| 邵阳县| 太白县| 江津市| 东港市| 太仓市| 驻马店市| 旅游| 全南县| 乐业县| 瑞丽市| 四会市| 德钦县| 永年县| 永善县| 盖州市|