Automapper

Automapper 顾名思义就是自动完成两个对象之间的copy,一个不错的教程:https://dotnettutorials.net/lesson/automapper-in-c-sharp/

不过这个教程的最后一节涉及到的UseValue 及 ResolveUsing 都已经停用了,目前有其他的方式,详见下面的例子中注释的5. 和 6. 。

 

 1 namespace TestAutoMapper
 2 {
 3     public class Address
 4     {
 5         public string City { get; set; }
 6         public string State { get; set; }
 7         public string Country { get; set; }
 8 
 9         public override string ToString()
10         {
11             return $"\n\tCity: {City}\n\tState: {State}\n\tCountry: {Country}";
12         }
13 
14     }
15 
16     public class Department
17     {
18         public string DeptName { get; set; }
19 
20         public string DeptCity { get; set; }
21 
22         public override string ToString()
23         {
24             return $"\n\tDeptName: {DeptName}\n\tDeptCity: {DeptCity}";
25         }
26     }
27 
28 
29     public class Employee
30     {
31         public string Name { get; set; }
32         public int Age { get; set; }
33         public int Salary { get; set; }
34         public Address Address { get; set; }
35         public Department Department { get; set; }
36         public string SchoolName { get; set; }
37         public string SchoolLoc { get; set; }
38         public string Dummy { get; set; }
39        
40 
41         public override string ToString()
42         {
43             return $"Name: {Name}\nAge: {Age}\nSalary: {Salary}\nAddress: {Address}\nDepartment: {Department}\nSchoolName: {SchoolName}\nSchoolLoc: {SchoolLoc}\nDummy: {Dummy}";
44         }
45     }
46 }
 1 using System;
 2 
 3 namespace TestAutoMapper
 4 {
 5     public class AddressDTO
 6     {
 7         public string CityName { get; set; }
 8         public string State { get; set; }
 9         public string Country { get; set; }
10 
11         public override string ToString()
12         {
13             return $"\n\tCityName:{CityName}\n\tState:{State}\n\tCountry:{Country}";
14         }
15     }
16 
17     public class SchoolDTO
18     {
19         public string SchoolName { get; set; }
20         public string SchoolLoc { get; set; }
21 
22         public override string ToString()
23         {
24             return $"\n\tSchoolName: {SchoolName}\n\tSchoolLoc: {SchoolLoc}";
25         }
26     }
27 
28     public class EmployeeDTO
29     {
30         public string FullName { get; set; }
31         public int Age { get; set; }
32         public int Salary { get; set; }
33         public AddressDTO AddressDTO { get; set; }
34         public string DeptName { get; set; }
35         public string DeptCity { get; set; }
36         public SchoolDTO SchoolInfo { get; set; }
37         public string Dummy { get; set; }
38         public string FixedItem { get; set; }
39         public DateTime UpdateTime { get; set; }
40         public override string ToString()
41         {
42             return $"FullName: {FullName}\nAge: {Age}\nSalary: {Salary}\nAddressDTO: {AddressDTO}\nDeptName: {DeptName}\nDeptCity: {DeptCity}\nSchoolInfo: {SchoolInfo}\nDummy: {Dummy}\nFixedValue: {FixedItem}\nUpdateTime: {UpdateTime}";
43         }
44     }
45 }

 

program.cs

 1 using AutoMapper;
 2 using System;
 3 
 4 namespace TestAutoMapper
 5 {
 6 
 7     class Program
 8     {
 9         static void Main()
10         {
11             var config = new MapperConfiguration(cfg =>
12             {
13                 cfg.CreateMap<Address, AddressDTO>()
14                 .ForMember(dest => dest.CityName, act => act.MapFrom(src => src.City));
15 
16                 cfg.CreateMap<Employee, EmployeeDTO>()
17                 .ForMember(dest => dest.Age, act => act.Condition(src => (src.Age > 40)))             // 1. condition mapping
18                 .ForMember(dest => dest.FullName, act => act.MapFrom(src => src.Name))                // 2. different name
19                 .ForMember(dest => dest.DeptName, act => act.MapFrom(src => src.Department.DeptName)) // 3. source itme is complex, target is primary
20                 .ForMember(dest => dest.DeptCity, act => act.MapFrom(src => src.Department.DeptCity))
21                 .ForMember(dest => dest.AddressDTO, act => act.MapFrom(src => src.Address))
22                 .ForMember(dest => dest.Dummy, act => act.Ignore())                                   // 4. Ignore item mapping
23                 .ForMember(dest => dest.FixedItem, act => act.MapFrom(src => "Fixed Value"))          // 5. set fixed value to target
24                 .ForMember(dest => dest.UpdateTime, act => act.MapFrom(src => DateTime.Now ))         // 6. set dynamic value to target
25                 .ForMember(dest => dest.SchoolInfo, act => act.MapFrom(src => new SchoolDTO()         // 7. source item is primary, target is complex
26                 {
27                     SchoolName = src.SchoolName,
28                     SchoolLoc = src.SchoolLoc
29                 }));
30             });
31 
32             Address empAddress = new Address
33             {
34                 City = "Mumbai",
35                 State = "Maharashtra",
36                 Country = "India"
37             };
38 
39             Department empDept = new Department
40             {
41                 DeptName = "IT",
42                 DeptCity = "NewYork"
43             };
44 
45             Employee emp = new Employee
46             {
47                 Name = "James",
48                 Age = 30,
49                 Salary = 20000,
50                 Address = empAddress,
51                 Department = empDept,
52                 SchoolName = "MIT",
53                 SchoolLoc = "USA",
54                 Dummy = "Dummy item will be ignore"
55             };
56 
57             var mapper = new Mapper(config);
58             var empDTO = mapper.Map<EmployeeDTO>(emp);
59 
60             var defaultColor = Console.ForegroundColor;
61             Console.ForegroundColor = ConsoleColor.Red;
62 
63             Console.WriteLine("Copy from:");
64             Console.WriteLine();
65             Console.WriteLine(emp);
66             Console.WriteLine();
67             Console.ForegroundColor = ConsoleColor.Green;
68             Console.WriteLine("to");
69             Console.WriteLine();
70             Console.WriteLine(empDTO);
71             Console.ForegroundColor = defaultColor;
72         }
73     }
74 }

这个例子也很直观:将一个类Employee 的对象的值复制到另一个类 EmployeeDTO 的对象。这两个类的属性有完全一样的,也有些区别。

复制的过程中会按照如下的规则(除了0之外,其他的都对应例子中的注释):

0. 属性相同的值会被直接复制不需要任何操作

1. 复制的时候可以加上条件,比如Age > 40才复制,否则不复制

2. 属性不一致的情况下需要额外定义,否则不会复制

3. 源数据的属性是一个复杂类型(一个类)Department,而目标是简单类型,需要明确给出对应关系

4. 如果某些属性不想复制,也可以设置为忽略 ignore

5. 给目标属性赋一个固定值

6. 给目标属性赋一个需要运算的值

7. 与 3. 相反,由简单类型复制到复杂类型

上面例子的输出如下:

 

注:本文中的例子为一个.NET console project, 使用 Nuget 安装一下 AutoMapper 即可。

posted @ 2022-05-25 17:30  脱缰的野猪  阅读(144)  评论(0编辑  收藏  举报