.Net core 中 AutoMapper的應用

葉大白丶發表於2019-05-16

   什麼是AutoMapper ?!

     Automapper是一個object-object mapping(物件對映)的DTO(資料傳輸)工具,一般主要用於兩個物件之間資料對映和交換。當然你也可以定義對映規則寫物件的對映。
     預設的對映規則是遵循的扁平化對映原則:只要Destination型別的成員名字與Source型別的成員名字匹配(成員名稱不區分大小寫),並且成員型別相同就直接會將值傳遞給Destination型別。
 


     以往我們進行資料實體的傳輸時的步驟應該是

            Customer customer = new Customer()
            {
                name = "葉大白",
                age = "24",
                adress = "合肥"
            };

            Customer2 customer2 = new Customer2()
            {
                name = customer.name,
                age = customer.age,
                adress = customer.adress
            };

    而現在僅僅只需要簡單一句話就可以全域性配置這種型別的轉換了

     var info2 = _mapper.Map<Customer2>(customer); 

 


AutoMapper的部署

1.引用Nuget包 => 

AutoMapper                                   
AutoMapper.Extensions.Microsoft.DependencyInjection      (輔助對映的擴充套件包)

      

2.注入服務 (在startup 的ConfigureServices中注入服務)

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

            services.AddAutoMapper();   //引用autoMapper的服務
        }

3.定義全域性對映規則  類繼承Profile

    //automapper的 對映規則。全域性通用。
    public class AutoMapperProfileConfiguration : Profile
    {
        //匹配規則 和路由匹配一致。從上到下掃描。取最下面的那個
        public AutoMapperProfileConfiguration()
        {
            CreateMap<Customer, Customer2>();  //建立的對映規則
        }
    }

4.專案中的使用

  
    [Route("api/test")]
    [ApiController]
    public class ValuesController : ControllerBase
    {
     
       private readonly IMapper _mapper;

       public ValuesController([FromServices] IMapper mapper) => _mapper = mapper;

       [HttpGet("Demo")]
       //automapperDemo
       public void AutoDemo()
       {
          var info = _mapper.Map<customer, customer2>(customer);
       }
    }

   automapper的匹配規則是從上至下的。 如果匹配多個符合條件預設取最後一個匹配到的規則形式。進行DTO轉換

 AutoMapper的應用場景 :

    public class Customer   //客戶
    {
        public string name { get; set; }
        public string age { get; set; }
        public string profession { get; set; }     //專業
    }

    public class Customer2   //客戶2
    {
        public string name { get; set; }
        public string age { get; set; }
        public string profession { get; set; }     //專業
    }

   場景1. 直接的轉換。

 新增的規則:  CreateMap<Customer, Customer2>();

  場景2.  customer2的欄位名字不對稱。


    public class Customer2   //客戶2
    {
        public string customername { get; set; }
        public string age { get; set; }
        public string profession { get; set; }     //專業
    }
 CreateMap<Customer, Customer2>()
     .ForMember(s => s.customername, sp => sp.MapFrom(src => src.name)); 
   //s指代的是對映後的欄位。  sp 指代的是對映源資料的來源欄位

場景3. 希望將對映後的資料進行部分資料的隱藏/更改


       CreateMap<Customer, Customer2>() //(source是源資料, dto是轉換後的對映的內容)
        //對映發生之前對資料的修改
        .BeforeMap((source, dto) =>
        {
           //可以較為精確的控制輸出資料格式
           //dto.CreateTime = Convert.ToDateTime(source.CreateTime).ToString("yyyy-MM-dd");
           //dto.customername
                    
        })
         //對映發生之後
        .AfterMap((source, dto) =>
        {
            dto.customername = source.name.Substring(0, 1) + "**";

             //if (dto.Count >0)
             //{
             //    dto = dto;
             //}
             //else
             //{
             //    dto = new List<customer4>();
             //}
        });

.beforeMapper是在對映發生之前。.aftermap是在對映發生之後  。除了可以寫業務也可以進行邏輯判斷等等同於個匿名方法。

場景4   List的轉換

   CreateMap<List<a>, List<a>>();
   var lista = new List<a>()
   {
         new a() { name = "a",age="18",adress="合肥" },
         new a() { name = "a",age="18",adress="合肥" },
         new a() { name = "a",age="18",adress="合肥" },
         new a() { name = "a",age="18",adress="合肥" }
   };
   
   var resultlist = _mapper.Map<List<b>>(lista);

場景5  自動分割對映(Flattening)

    public class Order
    {
        public Customer Customer { get; set; }
        public decimal GetTotal()
        {
            return 1;
        }
    }
    public class Customer
    {
        public string Name { get; set; }
    }

    public class OrderDto
    {
        public string CustomerName { get; set; }
        public decimal Total { get; set; }
    }
 CreateMap<Order, OrderDto>();

這種巢狀形式的實體對映,規則上和普通的實體對映一樣。因為遵循了自動分割對映原則。

  • 名稱相同的屬性進行對映,不區分大小寫。
  • 帶Get字首的方法進行對映,如例子中:
    對映器會把Order中的GetTotal分割成Get、Total 2個詞, 把分割出來的Total與OrderDto中的Order進行匹配對映。
  • 目標型別屬性分割,如例子中: 對映器會把OrderDto中的CustomerName分割成Customer、Name。然後在Order中去Customer類屬性中查詢Name的屬性。

 

場景-測試  如果想檢測我們的所有對映是否有效。新增一下程式碼。在匹配的地方。如果無效會丟擲異常。

Mapper.AssertConfigurationIsValid();

AssertConfigurationIsValid執行驗證期間,AutoMapper會檢查每個目標型別的屬性,逐一去匹配源中是否存在合適相等的型別,如果有欄位沒有對映成功就會丟擲異常。

 

本文參考文章: https://www.cnblogs.com/mushroom/p/4291975.html

 

 

 

相關文章