回顧
上節說到了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函數不過並不是很常用,其他的函數請自行研究,如果我有研究使用后面的系列我會一一分享。本節仍然是簡單的內容,如果大家有更好的建議請留言,我覺得可能搬運的太簡單,沒有給人具體的映象的感覺。
