AutoMapper 是一個對象-對象映射器,可以將一個對象映射到另一個對象。 官網(wǎng)地址:http:/// 1 入門例子public class Foo { public int ID { get; set; } public string Name { get; set; } } public class FooDto { public int ID { get; set; } public string Name { get; set; } } public void Map() { var config = new MapperConfiguration(cfg => cfg.CreateMap<Foo, FooDto>()); var mapper = config.CreateMapper(); Foo foo = new Foo { ID = 1, Name = "Tom" }; FooDto dto = mapper.Map<FooDto>(foo); } 2 注冊在使用 var config = new MapperConfiguration(cfg => cfg.CreateMap<Foo, FooDto>()); 每個 AppDomain 只能進(jìn)行一次配置。這意味著放置配置代碼的最佳位置是在應(yīng)用程序啟動中,例如 ASP.NET 應(yīng)用程序的 Global.asax 文件。 從 9.0 開始 2.1 Profile
public class EmployeeProfile : Profile { public EmployeeProfile() { CreateMap<Employee, EmployeeDto>(); } } var config = new MapperConfiguration(cfg => { cfg.AddProfile<EmployeeProfile>(); });
AutoMapper 也可以在指定的程序集中掃描從 var config = new MapperConfiguration(cfg => { // 掃描當(dāng)前程序集 cfg.AddMaps(System.AppDomain.CurrentDomain.GetAssemblies()); // 也可以傳程序集名稱(dll 名稱) cfg.AddMaps("LibCoreTest"); }); 3 配置3.1 命名約定默認(rèn)情況下,AutoMapper 基于相同的字段名映射,并且是 不區(qū)分大小寫 的。 但有時,我們需要處理一些特殊的情況。
我的理解,如果源類型和目標(biāo)類型分別采用了 蛇形命名法 和 駝峰命名法,那么就需要指定命名規(guī)則,使其能正確映射。 public class Foo { public int Id { get; set; } public string MyName { get; set; } } public class FooDto { public int ID { get; set; } public string My_Name { get; set; } } public void Map() { var config = new MapperConfiguration(cfg => { cfg.CreateMap<Foo, FooDto>(); cfg.SourceMemberNamingConvention = new PascalCaseNamingConvention(); cfg.DestinationMemberNamingConvention = new LowerUnderscoreNamingConvention(); }); var mapper = config.CreateMapper(); Foo foo = new Foo { Id = 2, MyName = "Tom" }; FooDto dto = mapper.Map<FooDto>(foo); } 3.2 配置可見性默認(rèn)情況下,AutoMapper 僅映射 var config = new MapperConfiguration(cfg => { cfg.ShouldMapProperty = p => p.GetMethod.IsPublic || p.SetMethod.IsPrivate; cfg.CreateMap<Source, Destination>(); }); 需要注意的是,這里屬性必須添加 3.3 全局屬性/字段過濾默認(rèn)情況下,AutoMapper 嘗試映射每個公共屬性/字段。以下配置將忽略字段映射。 var config = new MapperConfiguration(cfg => { cfg.ShouldMapField = fi => false; }); 3.4 識別前綴和后綴var config = new MapperConfiguration(cfg => { cfg.RecognizePrefixes("My"); cfg.RecognizePostfixes("My"); } 3.5 替換字符var config = new MapperConfiguration(cfg => { cfg.ReplaceMemberName("?", "A"); }); 這功能我們基本上用不上。 4 調(diào)用構(gòu)造函數(shù)有些類,屬性的 public class Commodity { public string Name { get; set; } public int Price { get; set; } } public class CommodityDto { public string Name { get; } public int Price { get; } public CommodityDto(string name, int price) { Name = name; Price = price * 2; } } AutoMapper 會自動找到相應(yīng)的構(gòu)造函數(shù)調(diào)用。如果在構(gòu)造函數(shù)中對參數(shù)做一些改變的話,其改變會反應(yīng)在映射結(jié)果中。如上例,映射后 禁用構(gòu)造函數(shù)映射: var config = new MapperConfiguration(cfg => cfg.DisableConstructorMapping()); 禁用構(gòu)造函數(shù)映射的話,目標(biāo)類要有一個無參構(gòu)造函數(shù)。 5 數(shù)組和列表映射數(shù)組和列表的映射比較簡單,僅需配置元素類型,定義簡單類型如下: public class Source { public int Value { get; set; } } public class Destination { public int Value { get; set; } } 映射: var config = new MapperConfiguration(cfg => { cfg.CreateMap<Source, Destination>(); }); IMapper mapper = config.CreateMapper(); var sources = new[] { new Source { Value = 5 }, new Source { Value = 6 }, new Source { Value = 7 } }; IEnumerable<Destination> ienumerableDest = mapper.Map<Source[], IEnumerable<Destination>>(sources); ICollection<Destination> icollectionDest = mapper.Map<Source[], ICollection<Destination>>(sources); IList<Destination> ilistDest = mapper.Map<Source[], IList<Destination>>(sources); List<Destination> listDest = mapper.Map<Source[], List<Destination>>(sources); Destination[] arrayDest = mapper.Map<Source[], Destination[]>(sources); 具體來說,支持的源集合類型包括:
5.1 處理空集合映射集合屬性時,如果源值為 5.2 集合中的多態(tài)這個官方的文檔不是很好理解。我重新舉個例子。實(shí)體類如下: public class Employee { public int ID { get; set; } public string Name { get; set; } } public class Employee2 : Employee { public string DeptName { get; set; } } public class EmployeeDto { public int ID { get; set; } public string Name { get; set; } } public class EmployeeDto2 : EmployeeDto { public string DeptName { get; set; } } 數(shù)組映射代碼如下: var config = new MapperConfiguration(cfg => { cfg.CreateMap<Employee, EmployeeDto>().Include<Employee2, EmployeeDto2>(); cfg.CreateMap<Employee2, EmployeeDto2>(); }); IMapper mapper = config.CreateMapper(); var employees = new[] { new Employee { ID = 1, Name = "Tom" }, new Employee2 { ID = 2, Name = "Jerry", DeptName = "R & D" } }; var dto = mapper.Map<Employee[], EmployeeDto[]>(employees); 可以看到,映射后, 如果去掉 6 方法到屬性映射AutoMapper 不僅能實(shí)現(xiàn)屬性到屬性映射,還可以實(shí)現(xiàn)方法到屬性的映射,并且不需要任何配置,方法名可以和屬性名一致,也可以帶有 例如下例的 public class Employee { public int ID { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string GetFullName() { return $"{FirstName} {LastName}"; } } public class EmployeeDto { public int ID { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string FullName { get; set; } } 7 自定義映射當(dāng)源類型與目標(biāo)類型名稱不一致時,或者需要對源數(shù)據(jù)做一些轉(zhuǎn)換時,可以用自定義映射。 public class Employee { public int ID { get; set; } public string Name { get; set; } public DateTime JoinTime { get; set; } } public class EmployeeDto { public int EmployeeID { get; set; } public string EmployeeName { get; set; } public int JoinYear { get; set; } } 如上例, var config = new MapperConfiguration(cfg => { cfg.CreateMap<Employee, EmployeeDto>() .ForMember("EmployeeID", opt => opt.MapFrom(src => src.ID)) .ForMember(dest => dest.EmployeeName, opt => opt.MapFrom(src => src.Name)) .ForMember(dest => dest.JoinYear, opt => opt.MapFrom(src => src.JoinTime.Year)); }); 8 扁平化映射對象-對象映射的常見用法之一是將復(fù)雜的對象模型并將其展平為更簡單的模型。 public class Employee { public int ID { get; set; } public string Name { get; set; } public Department Department { get; set; } } public class Department { public int ID { get; set; } public string Name { get; set; } } public class EmployeeDto { public int ID { get; set; } public string Name { get; set; } public int DepartmentID { get; set; } public string DepartmentName { get; set; } } 如果目標(biāo)類型上的屬性,與源類型的屬性、方法都對應(yīng)不上,則 AutoMapper 會將目標(biāo)成員名按駝峰法拆解成單個單詞,再進(jìn)行匹配。例如上例中, 8.1 IncludeMembers如果屬性命名不符合上述的規(guī)則,而是像下面這樣: public class Employee { public int ID { get; set; } public string Name { get; set; } public Department Department { get; set; } } public class Department { public int DepartmentID { get; set; } public string DepartmentName { get; set; } } public class EmployeeDto { public int ID { get; set; } public string Name { get; set; } public int DepartmentID { get; set; } public string DepartmentName { get; set; } }
var config = new MapperConfiguration(cfg => { cfg.CreateMap<Employee, EmployeeDto>().IncludeMembers(e => e.Department); cfg.CreateMap<Department, EmployeeDto>(); }); 9 嵌套映射有時,我們可能不需要展平??慈缦吕樱?/p> public class Employee { public int ID { get; set; } public string Name { get; set; } public int Age { get; set; } public Department Department { get; set; } } public class Department { public int ID { get; set; } public string Name { get; set; } public string Heads { get; set; } } public class EmployeeDto { public int ID { get; set; } public string Name { get; set; } public DepartmentDto Department { get; set; } } public class DepartmentDto { public int ID { get; set; } public string Name { get; set; } } 我們要將 var config = new MapperConfiguration(cfg => { cfg.CreateMap<Employee, EmployeeDto>(); cfg.CreateMap<Department, DepartmentDto>(); }); |
|