標籤:style blog http color os 使用 ar strong sp
寫在前面
知道AutoMapper很久了,但是一直沒有用,最近剛好有個情境需要就用了,果然是利器。看了git上的wiki,發現內容其實wiki上寫的很全面了,深入的暫時還沒挖掘到。不過和群裡的朋友交流了下,覺得充當下搬運工,小小的翻譯下還是挺好的,小弟不才,希望看客大牛們輕拍磚。
什麼是AutoMapper?
AutoMapper是一個完善的Mapping工具,所謂Mapping即資料對象轉換,借用群裡朋友的話是多用於領域對象和DTO對象的Mapping或者是SqlDataReader的Mapping。
Git首頁:https://github.com/AutoMapper/AutoMapper
Wiki首頁:https://github.com/AutoMapper/AutoMapper/wiki
簡單的例子
情境是這樣的在訂單業務裡,有Order、Customer、Product三個對象如下,其中Product被包含在OrderLinItem對象中:
1 public class Order 2 { 3 private readonly IList<OrderLineItem> _orderLineItems = new List<OrderLineItem>(); 4 5 public Customer Customer { get; set; } 6 7 public OrderLineItem[] GetOrderLineItems() 8 { 9 return _orderLineItems.ToArray();10 }11 12 public void AddOrderLineItem(Product product, int quantity)13 {14 _orderLineItems.Add(new OrderLineItem(product, quantity));15 }16 17 public decimal GetTotal()18 {19 return _orderLineItems.Sum(li => li.GetTotal());20 }21 }22 }23 24 public class OrderLineItem25 {26 public OrderLineItem(Product product, int quantity)27 {28 Product = product;29 Quantity = quantity;30 }31 32 public Product Product { get; private set; }33 public int Quantity { get; private set;}34 35 public decimal GetTotal()36 {37 return Quantity*Product.Price;38 }39 }40 41 public class Customer42 {43 public string Name { get; set; }44 }45 46 public class Product47 {48 public decimal Price { get; set; }49 public string Name { get; set; }50 }View Code
然後在頁面上我需要展示一些資料,為了保持頁面ViewModel的獨立,定義一個DTO(OrderDto)只包含了頁面需要的欄位,如下:
public class OrderDto{ public string CustomerName { get; set; } public decimal Total { get; set; }}View Code
然後問題來了,怎麼轉換呢?
我想最簡單的方法肯定是這樣子:
//定義一個ordervar customer = new Customer{ Name = "George Costanza";}var order = new Order{ Customer = customer;}var bosco = new Product{ Name = "Bosco", Price = 4.99m;}order.AddOrderLineItem(bosco, 15);//轉換var dto = new OrderDto();dto.CustomerName = order.Customer.Name;dto.Total = order.GetTotal();
上面的代碼看起來很簡單沒什麼問題,但是如果dto屬性有很多個呢?反覆的手動Mapping會不會有點累?這時候攻城獅就得發揮偷懶精神,以下是使用了AutoMapper的代碼:
// 配置一個 AutoMapper 映射Mapper.CreateMap<Order, OrderDto>();// 執行 mappingOrderDto dto = Mapper.Map<Order, OrderDto>(order);
是不是很簡單簡潔了,但是細心的會發現,這個Mapping稍微有點複雜,CustomerName對應的是order.Customer.Name;Total對應的是GetTotal方法。AutoMaper是如何做到,又是如何定義這個規則的呢?
AutoMapper的簡單預設Mapping規則
1. 針對複雜物件到簡單對象的映射,Mapping遵循駝峰命名的規則,即當目標dto屬性名稱在來源物件中找不到時,AutoMapper會根據駝峰命名規則拆分dto屬性名稱(例如:CustomerName=>Customer.Name)去尋找相應的關係。
2. 針對是來源物件中存在Get開頭的屬性(例如 Total => GetTotal),如果找不到同名屬性,則會匹配Get+PropertyName的方法。
本文搬運自AutoMapper Wiki之Flattening:https://github.com/AutoMapper/AutoMapper/wiki/Flattening
上面的規則是最簡單的匹配規則,對於複雜的Mapping,完全不符合上面的兩條特性的,那麼就需要進行Mapping的自訂配置,下節 《AutoMapper之自訂映射》裡,我會為大家搬運。有啥疑問和意見可以給我留言,咱們來探討一番,請大拿不吝賜教~!
AutoMapper搬運工之初探AutoMapper