ASP.NET Core 3.1使用AutoMapper(基本使用)


 

AutoMapper定義

AutoMapper是一個OOM(Object-Object-Mapping)組件,從它的英文名字中可以看出,AutoMapper主要是為了實現實體間的相互轉換,從而避免我們每次采用手工的方式進行轉換。在沒有OOM這類組件之前,如果我們需要實現實體之間的轉換,只能使用手工修改代碼,然后逐個賦值的方式實現映射,而有了OOM組件,可以很方便的幫助我們實現這一需求。

 

在學習EF的時候我們知道了ORM(Object Relational Mapping)映射,是一種對象關系的映射,對象-關系映射(ORM)系統一般以中間件的形式存在,主要實現程序對象到關系數據庫數據的映射。而Automapper是一種實體轉換關系的模型,AutoMapper是一個.NET的對象映射工具。主要作用是進行領域對象與模型(DTO)之間的轉換、數據庫查詢結果映射至實體對象。

下邊的是基本原理,大家喵一眼就行:

Ø 什么是DTO?

  數據傳輸對象(DTO)(DataTransfer Object),是一種設計模式之間傳輸數據的軟件應用系統。數據傳輸目標往往是數據訪問對象從而從數據庫中檢索數據。數據傳輸對象與數據交互對象或數據訪問對象之間的差異是一個以不具有任何行為除了存儲和檢索的數據(訪問和存取器)。

Ø 為什么用?
  它的目的只是為了對領域對象進行數據封裝,實現層與層之間的數據傳遞。為何不能直接將領域對象用於數據傳遞?因為領域對象更注重領域,而DTO更注重數據。不僅如此,由於“富領域模型”的特點,這樣做會直接將領域對象的行為暴露給表現層。

  需要了解的是,數據傳輸對象DTO本身並不是業務對象。數據傳輸對象是根據UI的需求進行設計的,而不是根據領域對象進行設計的。比如,Customer領域對象可能會包含一些諸如FirstName, LastName, Email, Address等信息。但如果UI上不打算顯示Address的信息,那么CustomerDTO中也無需包含這個 Address的數據”。

Ø 什么是領域對象?
  領域模型就是面向對象的,面向對象的一個很重要的點就是:“把事情交給最適合的類去做”,即:“你得在一個個領域類之間跳轉,才能找出他們如何交互”。在我們的系統中Model(EF中的實體)就是領域模型對象。領域對象主要是面對業務的,我們是通過業務來定義Model的。

 

配置AutoMapper

步驟一:引入Nuget程序包:AutoMapper 和 AutoMapper.Extensions.Microsoft.DependencyInjection

AutoMapper.Extensions.Microsoft.DependencyInjection,這個是用來配合依賴注入的;

步驟二:添加映射類 CustomProfile.cs

在你的項目中,添加一個AutoMapper文件夾(非必須),在新建個類,取名CustomProfile(這個名字可以自定義),此類必須繼承於Profile,用來匹配所有的映射對象關系

 1 using AutoMapper;
 2 using GreenUnity.EntityFramework.Models;
 3 using QG_EnterpriseAccountAPi.RequestModels;
 4 using System;
 5 using System.Collections.Generic;
 6 using System.Text;
 7 
 8 namespace QG_EnterpriseAccountAPi.AutoMapper
 9 {
10     public class CustomProfile : Profile
11     {
12         /// <summary>
13         /// 配置構造函數,用來創建關系映射
14         /// </summary>
15         public CustomProfile()
16         {
17             //第一個參數是原對象,第二個是目的對象。ReverseMap代表着兩個對象能夠相互轉換
18             CreateMap<Enterpriseowncheck,TbEnterpriseowncheck>().ReverseMap();
19 
20         }
21     }
22 }
CustomProfile

Profile不知有什么用,通過百度了解才了解是services.AddAutoMapper是會自動找到所有繼承了Profile的類然后進行配置,而且我的這個配置文件是在api層的,如果Profile配置類放在別的層(比如Service層),如果沒解耦的話,可以services.AddAutoMapper(),參數留空,AutoMapper會從所有引用的程序集里找繼承Profile的類,如果解耦了,就得services.AddAutoMapper(Assembly.Load("Blog.Core.Service"))。

Profile的用處在於告訴AutoMapper服務去哪里找映射關系,  在DI注入AutoMapper服務的時候如果繼承Profile的類的程序集沒有跟主項目解耦,就會去引用的程序集中找到所有繼承Profile的類,如果解耦了,就需要使用反射加載繼承Profile的類的程序集。

 

注入AutoMapper

在Startup中,注入服務

   #region AutoMappe
            services.AddAutoMapper(typeof(Startup));//這是AutoMapper的2.0新特性
            //services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());//與上面注入方式無區別
            //services.AddAutoMapper(Assembly.Load("程序集Dll名稱"));//解耦時需要使用反射加載程序集
            #endregion
Startup注入AutoMappe

 

使用AutoMapper模型映射

 

 

1.在需要使用AutoMapper模型映射的類中注入IMapper

  IMapper _IMapper;
        public EnterpriseOwnCheckController(UnitOfWork unit, ILogger<UserController> logger, IMapper IMapper) : base(unit, logger)
        {
            _IMapper = IMapper;//構造函數注入IMapper
        }
注入IMapper

 

2.使用IMapper對象的Map方法實現對象的映射

 //注意:<>里是需要轉換成的對象(對象名稱)。()里是被轉換的對象(已實列化的對象名)
var TbEnterpriseowncheck = _IMapper.Map<TbEnterpriseowncheck>(enterpriseowncheck); 
使用Map方法進行映射

 

復雜深拷貝映射

有的小伙伴問,你這個這個簡單,都是相同字段的,那當然很方便啦,要是一個復雜的,比如屬性名字不一樣的,或者說有子類等嵌入型的咋辦?放心,一樣是可以的,請看

1、屬性名稱不一樣(手動告訴AutoMapper 屬性名稱不一樣的字段分別對應哪些字段
  CreateMap<Student, StudentViewModel>()
       .ForMember(d => d.CountyName, o => o.MapFrom(s => s.County))
       .ForMember(d => d.ProvinceName, o => o.MapFrom(s => s.Province));

 

2、如果是還有子類的復雜類型
CreateMap<Student, StudentViewModel>()
      .ForMember(d => d.County, o => o.MapFrom(s => s.Address.County))
      .ForMember(d => d.Province, o => o.MapFrom(s => s.Address.Province))
      .ForMember(d => d.City, o => o.MapFrom(s => s.Address.City))
      .ForMember(d => d.Street, o => o.MapFrom(s => s.Address.Street))
      ;


   public class Student : Entity
    {
        public string Name { get; private set; }
        public string Email { get; private set; }
        public string Phone { get; private set; }
        public DateTime BirthDate { get; private set; }
        public Address Address { get; private set; }
    }

    public class StudentViewModel
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
        public string Email { get; set; }
        public DateTime BirthDate { get; set; }
        public string Phone { get; set; }
        public string Province { get; set; }
        public string City { get; set; }
        public string County { get; set; }
        public string Street { get; set; }
    }

 

 

大部分資料參考來源:https://www.cnblogs.com/laozhang-is-phi/p/9565227.html#autoid-5-4-0

 

AutoMapper官網:https://docs.automapper.org/en/latest/index.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM