ASP.NET Core MVC 從入門到精通之自動映射(二)

隨着技術的發展,ASP.NET Core MVC也推出了好長時間,經過不斷的版本更新迭代,已經越來越完善,本系列文章主要講解ASP.NET Core MVC開發B/S系統過程中所涉及到的相關內容,適用於初學者,在校畢業生,或其他想從事ASP.NET Core MVC 系統開發的人員。

經過前幾篇文章的講解,初步瞭解ASP.NET Core MVC項目創建,啓動運行,以及命名約定,創建控制器,視圖,模型,接收參數,傳遞數據ViewData,ViewBag,路由,頁面佈局,wwwroot和客戶端庫,Razor語法,EnityFrameworkCore與數據庫,HttpContext,Request,Response,Session,序列化,文件上傳,自動映射等內容,今天繼續講解ASP.NET Core MVC 中自動映射第二部分等相關內容,僅供學習分享使用。

經過上一篇文章的講解,已經對ASP.NET Core中進行自動映射,有了一個初步的瞭解,今天繼續接着上一篇文章進行講解自動映射的第二部分內容。

字符替換

在實際開發中,如果映射源存在一些特殊字符【如:ë ,Ă等】,映射目標是正常的字符,則需要進行替換,才能映射。如下所示:

1 var configuration = new MapperConfiguration(c =>
2 {
3     c.ReplaceMemberName("Ä", "A");
4     c.ReplaceMemberName("í", "i");
5     c.ReplaceMemberName("Airlina", "Airline");
6 });

進行以上配置之後,會自動將Äbc映射到Abc上,將íng映射到ing上,將AirlinaMark映射到AirlineMark上。

自動映射匹配前綴與後綴

數據源一般都會有固定的風格,如帶有前綴,後綴等標識。那麼如何將帶前綴的屬性映射到不帶前綴的的屬性上呢?

默認情況下,帶前綴是無法自動映射的。如下錯誤示例,映射源有一個前綴s,映射目標沒有,則無法進行自動映射。如下:

可以在映射匹配文件中,增加映射前綴RecognizePrefixes("s"),如下所示:

 1 namespace DemoCoreMVC.Profiles
 2 {
 3     public class AutomapProfile:Profile
 4     {
 5         public AutomapProfile()
 6         {
 7             RecognizePrefixes("s");
 8             SourceMemberNamingConvention = new LowerUnderscoreNamingConvention();
 9             DestinationMemberNamingConvention = new PascalCaseNamingConvention();
10             //創建映射關係
11             CreateMap<StudentViewModel, Student>();
12         }
13     }
14 }

經過前綴設置後,則可以進行自動映射,如下所示:

關於映射匹配前綴後綴設置,有以下幾點需要注意:

  1. 一般前綴都是具有一定規律的設置,否則有些前綴a,有些前綴b,沒有一定的規律,則無法完全匹配。
  2. 後綴通過RecognizePostfixes("s");設置即可,功能測試與前綴一致。
  3. 取消前綴設置ClearPrefixes();就是取消所有的前綴設置列表中設置的前綴。Automapper默認匹配了Get前綴,如果不需要可以清除。

映射控制(不常用)

使用ShouldMapField和ShouldMapProperty控制哪些屬性和字段能夠被映射

1 cfg.ShouldMapField = fi => false;
2 cfg.ShouldMapProperty = pi =>pi.GetMethod != null && (pi.GetMethod.IsPublic || pi.GetMethod.IsPrivate);

默認所有public的field和property都會被map,也會map private 的setter,但是不會map整個property都是internal/private的屬性。

列表映射

在實際工作中,列表的應用場景還是比較多的,列表映射也比較常用。如下所示:

1 [HttpPost]
2 public IActionResult Add(StudentViewModel studentViewModel)
3 {
4     var listStudents=new List<StudentViewModel>();
5     listStudents.Add(studentViewModel);
6     var students =  mapper.Map<List<StudentViewModel>,List< Student>>(listStudents);
7     studentService.Adds(students);
8     return View();
9 }

經過測試發現,只要映射了元素類型,列表可以自動映射。如下所示:

 AutoMapper默認會自動映射以下類型:

  • IEnumerable
  • IEnumerable<T>
  • ICollection
  • ICollection<T>
  • IList
  • IList<T>
  • List<T>
  • Arrays

這幾個集合之間可以相互映射,如:mapper.Map<Source[], IEnumerable<Destination>>(sources);

手動控制映射(不常用)

如果對於完全沒有任何規律的映射,如何進行呢?如下兩個映射數據類型:
映射源類型:

 1 namespace DemoCoreMVC.ViewModels
 2 {
 3     public class UserViewModel
 4     {
 5         public int UserId { get; set; }
 6 
 7         public string UserName { get; set; }
 8 
 9         public string Mail { get; set; }
10     }
11 }

映射目標類型:

 1 namespace DemoCoreMVC.Models
 2 {
 3     public class User
 4     {
 5         public int Id { get; set; }
 6 
 7         public string Name { get; set; }
 8 
 9         public string Email { get; set; }
10     }
11 }

需要手動配置映射屬性列,如下所示:

 1 public class AutomapProfile:Profile
 2 {
 3     public AutomapProfile()
 4     {
 5         RecognizePrefixes("s");
 6         //RecognizePostfixes("s");
 7         SourceMemberNamingConvention = new LowerUnderscoreNamingConvention();
 8         DestinationMemberNamingConvention = new PascalCaseNamingConvention();
 9         //創建映射關係
10         CreateMap<StudentViewModel, Student>();
11         //ClearPrefixes();
12 
13         CreateMap<UserViewModel, User>()
14             .ForMember(dest => dest.Id, opt => opt.MapFrom(source => source.UserId))
15             .ForMember(dest => dest.Name, opt => opt.MapFrom(source => source.UserName))
16             .ForMember(dest => dest.Email, opt => opt.MapFrom(source => source.Mail));
17     }
18 }

映射示例

通過手動配置映射列後,就可以實現自動映射,如下所示:

1 public IActionResult Add(UserViewModel userViewModel)
2 {
3    
4     var user =  mapper.Map<UserViewModel,User>(userViewModel);
5     
6     return View();
7 }

手動映射測試結果如下:

 注意:手動映射主要適用於屬性完全不一致,沒有前綴,後綴,任何規律可言的屬性映射的情況,所以一般不太常用。

嵌套映射

對於複雜的嵌套類型,對象的屬性可能是一個複雜引用類型對象。

映射源,其中屬性User爲類型爲UserViewModel的引用類型。如下所示:

1 namespace DemoCoreMVC.ViewModels
2 {
3     public class EmployeeViewModel
4     {
5         public int Id { get; set; }
6 
7         public UserViewModel User { get; set; }
8     }
9 }

映射目標,其中屬性Uer爲類型爲User的引用類型。如下所示:

1 namespace DemoCoreMVC.Models
2 {
3     public class Employee
4     {
5         public int Id { get; set; }
6 
7         public User User { get; set; }
8     }
9 }

如果要對應複雜的存在嵌套關係的對象進行映射,則需要對屬性類型也進行創建映射關係。如下所示:

1 CreateMap<UserViewModel, User>()
2     .ForMember(dest => dest.Id, opt => opt.MapFrom(source => source.UserId))
3     .ForMember(dest => dest.Name, opt => opt.MapFrom(source => source.UserName))
4     .ForMember(dest => dest.Email, opt => opt.MapFrom(source => source.Mail));
5 CreateMap<EmployeeViewModel,Employee>();

在控制器中調用,如下所示:

1 public IActionResult Add(UserViewModel userViewModel)
2 {
3     EmployeeViewModel employeeViewModel = new EmployeeViewModel() { Id = 1, User = userViewModel };
4     var employee = mapper.Map<EmployeeViewModel, Employee>(employeeViewModel);
5 
6     return View();
7 }

運行測試,如下所示:

 

以上就是ASP.NET Core MVC從入門到精通之自動映射的第二部分的全部內容。

大家也可以參考以下文章連接,講解的更加詳細:https://blog.csdn.net/catshitone/article/details/109840926。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章