程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 【AutoMapper官方文檔】DTO與Domin Model相互轉換(上)

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

編輯:C#入門知識

前言

 》,因為內容寫的有點跑偏,關於AutoMapper的使用最後只是簡單寫了下,很明顯這種簡單的使用方式不能滿足項目中復雜的需要,網上找了下AutoMapper相關文檔,但差不多都是像我一樣簡單的概述下,看來懶的不只有我一個,哈哈。在AutoMapper 官方文檔中找到其使用的詳細說明,天書一樣的英文,然後就找相關中文文檔,最後還是沒找到,這邊沒辦法,只能自己動手,豐衣足食了。英語牛逼的可以直接略過,查看英文文檔,本篇也不算是翻譯,因為本人英語實在拿不出手,只是按照示例加上自己的一些理解,做個學習筆記,不對的地方還請指正。

  

Flattening-復雜到簡單

                  IList<OrderLineItem> _orderLineItems =  List<OrderLineItem>          Customer Customer { ;                                    AddOrderLineItem(Product product,               _orderLineItems.Add(                          _orderLineItems.Sum(li =>   
                  Price { ;            Name { ;   
                 OrderLineItem(Product product,               Product =             Quantity =           Product Product { ;             Quantity { ;                           Quantity *   
                  Name { ;   
                  CustomerName { ;            Total { ;      }

                         customer =                   Name = 
               order =                   Customer =               bosco =                   Name =                  Price = 
              order.AddOrderLineItem(bosco,              
             Mapper.CreateMap<Order, OrderDto>             
             OrderDto dto = Mapper.Map<Order, OrderDto>           }

Order和OrderDto之間的類型映射就可以了,我們看OrderDto中的CustomerName和Total屬性在領域模型Order中並沒有與之相對性,沒什麼可以轉換呢,感覺好神奇的樣子,其實仔細發現這些屬性的命名都有一定的規則,AutoMapper在做解析的時候會按照PascalCase(帕斯卡命名法),就是一種變量命名法,除了PascalCase還有Hungarian(匈牙利命名法)和camelCase(駱駝命名法),PascalCase就是指混合使用大小寫字母來構成變量和函數的名字,首字母要大寫,camelCase首字母小寫,我們C#命名中,一般使用的是camelCase和PascalCase,比較高級的是PascalCase。

  但是為什麼AutoMapper會解析Total呢?因為在領域模型Order中有個GetTotal()方法,AutoMapper會解析“Get”之後的單詞,所以會與Total相對應,如果你把OrderDto的屬性“Total”改為“Totals”,就會發現得到的“Totals”為0。理解了AutoMapper的解析方式,我們就要注意在編寫變量、屬性或是方法名稱的時候一定要規范,這也是一種好的習慣。

Projection-簡單到復雜

Flattening是由復雜結構簡化,Projection正好相反,投影可以理解為由原始結構千變萬化,我們看下兩種轉換結構:

                 DateTime EventDate { ;            Title { ;   
                 DateTime EventDate { ;            EventHour { ;            EventMinute { ;            Title { ;      }

                         calendarEvent =                   EventDate =  DateTime(, , , , ,                  Title = 
  
             
             Mapper.CreateMap<CalendarEvent, CalendarEventForm>                 .ForMember(dest => dest.EventDate, opt => opt.MapFrom(src => src.EventDate.Date))
                 .ForMember(dest => dest.EventHour, opt => opt.MapFrom(src => src.EventDate.Hour))
                 .ForMember(dest => dest.EventMinute, opt => opt.MapFrom(src => src.EventDate.Minute)); 
             
             CalendarEventForm form = Mapper.Map<CalendarEvent, CalendarEventForm> 
             Console.WriteLine(+             Console.WriteLine( +             Console.WriteLine( +             Console.WriteLine( +         }

MapFrom方法中做一些復雜的映射關系操作,MapFrom接受一個lambda表達式作為參數,可以是任何的Func表達式。Projection適用於由簡單到復雜的結構映射,一般體現在業務場景很復雜的情況下。

Projection就是把AutoMapper的映射配置交給用戶來操作】

Configuration Validation-配置驗證

PascalCase命名法,或者說我們命名是錯誤的,該怎麼辦呢?比如下面代碼:

                          SomeValue { ;   
                          SomeValuefff { ;          }

AutoMapper映射:

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

AutoMapper提供了Ignore方法,忽略不需要映射的數據結構,我們這樣配置就可以了:

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

Lists and Array-集合和數組

                                 sources =                            Source {Value =                           Source {Value =                           Source {Value =                   
                 Mapper.Initialize(cfg =>
                      cfg.CreateMap<Source, Destination>                  
                 IEnumerable<Destination> ienumerableDest = Mapper.Map<Source[], IEnumerable<Destination>>                 ICollection<Destination> icollectionDest = Mapper.Map<Source[], ICollection<Destination>>                 IList<Destination> ilistDest = Mapper.Map<Source[], IList<Destination>>                 List<Destination> listDest = Mapper.Map<Source[], List<Destination>> 
                 Console.WriteLine( +                 Console.WriteLine( +                 Console.WriteLine( +                 Console.WriteLine( +             }

來源類型支持上述集合類型,我們可以把來源類型省略掉,因為AutoMapper會自動判斷傳入對象sources的類型,如下:

                 IEnumerable<Destination> ienumerableDest = Mapper.Map<IEnumerable<Destination>>                 ICollection<Destination> icollectionDest = Mapper.Map<ICollection<Destination>>                 IList<Destination> ilistDest = Mapper.Map<IList<Destination>>                 List<Destination> listDest = Mapper.Map<List<Destination>>(sources);

                                  Value1 { ;                                    Value2 { ;                                    Value1 { ;                                    Value2 { ;              }

                                 sources =                                                                                               
                 Mapper.Initialize(cfg =>
                      cfg.CreateMap<ParentSource, ParentDestination>                         .Include<ChildSource, ChildDestination>                     cfg.CreateMap<ChildSource, ChildDestination>                  
                  destinations = Mapper.Map<ParentSource[], ParentDestination[]>                 Console.WriteLine( + destinations[                 Console.WriteLine( + destinations[                 Console.WriteLine( + destinations[             }

AutoMapperMappingException”異常,但是可以看出AutoMapper並沒有從ChildSource類型映射到ChildDestination類型,而是自動映射到基類型,上面那段映射代碼只是說明派生類和基類之間存在的關系,如果派生類需要映射的話,是需要添加派生類的映射的。

Nested mappings-嵌套映射

  

                                  Value { ;                   InnerSource Inner { ;                                    OtherValue { ;                                    Value { ;                   InnerDest Inner { ;                                    OtherValue { ;              }

                                 source =                       Value =                      Inner =  InnerSource { OtherValue =                   
                 Mapper.CreateMap<OuterSource, OuterDest>                 Mapper.CreateMap<InnerSource, InnerDest>                 
                  
                  dest = Mapper.Map<OuterSource, OuterDest>                 Console.WriteLine( +                 Console.WriteLine( + (dest.Inner ==  ?  :                  Console.WriteLine( +             }

AutoMapperMappingException”異常來判斷類型映射是否正確,因為AssertConfigurationIsValid方法沒有返回值,只能在catch中捕獲了,個人感覺AutoMapper可以提供個bool類型的返回值,驗證成功則返回true。

後記

AutoMapper在配置類型映射最注意的一點是,類型中的名稱一定要按照PascalCase命名規則(Projection和Ignore除外)。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved