程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> AutoMapper搬運工之自定義映射,automapper搬運工

AutoMapper搬運工之自定義映射,automapper搬運工

編輯:C#入門知識

AutoMapper搬運工之自定義映射,automapper搬運工


回顧

上節說到了AutoMapper的簡單使用,對於復雜的Mapping需要強大的自定義,這節我們來看下AutoMapper的自定義Mapping(Projection)

搬運自Git:https://github.com/AutoMapper/AutoMapper/wiki/Projection

 

 

實例

本篇的場景是一個簡單的日歷事件,我們首先定義一個日歷的事件如下:

1 public class CalendarEvent
2 {
3     //事件日期  
4     public DateTime Date { get; set; }
5     //事件標題     
6     public string Title { get; set; }
7 }

 

那麼在頁面,我們需要顯示這個事件的具體信息,而且是可編輯的,定義一個ViewModel dto如下:

 1 public class CalendarEventForm
 2 {
 3     //事件日期
 4     public DateTime EventDate { get; set; }
 5     //時間對應的小時
 6     public int EventHour { get; set; }
 7     //時間對應的分鐘
 8     public int EventMinute { get; set; }
 9     //事件標題
10     public string Title { get; set; }
11 }

 

也許你會小小的糾結下,為啥要這麼定義,頁面上js直接轉換之類的,好吧,這就是一個例子,你明白就好。

 

接下來和本系列一貫的做法一樣,我們來看下手寫Mapping的方式:

 1 // 定義一個日歷事件
 2 var calendarEvent = new CalendarEvent
 3 {
 4     Date = new DateTime(2014, 12, 15, 20, 30, 0),
 5     Title = "公司聚會"
 6 };
 7 
 8 CalendarEventForm form = new CalendarEventForm
 9 {
10     EventDate = calendarEvent.Date.Date,
11     EventHour =  calendarEvent.Date.Hour,
12     EventMinute = calendarEvent.Date.Minute,
13     Title = calendarEvent.Title  
14 };

 

這個Mapping依然很簡單,沒什麼疑問,咱們來對比下使用AutoMapper:

1 // 配置Mapping
2 Mapper.CreateMap<CalendarEvent, CalendarEventForm>()
3         .ForMember(dest => dest.EventDate, opt => opt.MapFrom(src => src.Date.Date))
4         .ForMember(dest => dest.EventHour, opt => opt.MapFrom(src => src.Date.Hour))
5         .ForMember(dest => dest.EventMinute, opt => opt.MapFrom(src => src.Date.Minute));
6 
7 //Mapping
8 CalendarEventForm form = Mapper.Map<CalendarEvent, CalendarEventForm>(calendarEvent);

 

有什麼感想?是不是感覺代碼高大上,但是跟手寫的沒啥區別,哈哈,別著急,這只是一個例子。對於復雜的場景,你自然會體會到AutoMapper使代碼簡潔,配置統一。

說道配置這裡需要說明一下:Mapping的配置並不是這樣每次都要Create的,具體的說明,請期待下篇 《AutoMapper之配置》

回到上面的代碼,我們來進一步的說明下這個ForMember

 

ForMember函數

AutoMapper提供了相關的API來支持自定義的Mapping配置,並且他支持lamda哦。

看一下ForMember的定義:

 1 IMappingExpression<TSource, TDestination> ForMember(Expression<Func<TDestination, object>> destinationMember 

第一個參數是目標屬性,第二個參數是一定義的映射Expression, Expression讓這個映射變得更加的動態,可以直接使用表達式或者干脆直接來個函數調用:

 1 .ForMember(dest => dest.Title, opt => opt.MapFrom(src => ChangeTitle(src.Title));//調用方法
 2 .ForMember(dest => dest.Title, opt => opt.MapForm(src => src.Title.Where(....);//表達式
 3 
 4 string ChangeTitle(string title)
 5 {
 6     //自定義處理
 7     ...
 8     
 9     return "myName" + title;  
10 }

 有關Expression的內容及構造請參考表達式的文章,這裡邊的水很深,有機會我也去深入研究分享些內容。

 細心的你或許會發現,如果映射寫了多個會怎麼樣?經過測試,結論是:只有第一個配置是有效的,之後的同參數映射AutoMapper會自動忽略。

另外,還有一個ForMembers函數不過並不是很常用,其他的函數請自行研究,如果我有研究使用後面的系列我會一一分享。本節仍然是簡單的內容,如果大家有更好的建議請留言,我覺得可能搬運的太簡單,沒有給人具體的映象的感覺。 


automapper在ORM中的作用,教?

AutoMapper?舉個最簡單的例子。
比如在ORM中,與數據庫交互用的Model模型是具有很多屬性變量方法神馬的。而當我們與其它系統(或系統中的其它結構)進行數據交互時,出於耦合性考慮或者安全性考慮或者性能考慮(總之就是各種考慮),我們不希望直接將這個Model模型傳遞給它們,這時我們會創建一個貧血模型來保存數據並傳遞。神馬是貧血模型?貧血模型(DTO,Data Transfer Object)就是說只包含屬性神馬的,只能保存必須的數據,木有其它任何的多余的方法數據什麼的,專門用於數據傳遞用的類型對象。在這個創建的過程中,如果我們手動來進行,就會看到這樣的代碼:
B b=new B();
b.XXX1=a.XXX1;
b.XXX2=a.XXX2;
...
...
...
return b;

此時,AutoMapper可以發揮的作用就是根據A的模型和B的模型中的定義,自動將A模型映射為一個全新的B模型。從而避免寫這樣又臭又長又無聊的代碼。SO,理解為代碼生成器也可以……
 


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