.Net Core 常用类库 AutoMapper
1 AutoMapper
同一个数据实体,在不同场合需要转换成不同模式的情况
映射两个对象之间的映射,一般是数据模型映射到视图模型,如果没有AutoMapper 需要手动处理费时费力

包 AutoMapper
同名部分大小写会自动映射
////// 映射源 /// public class Student { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } public string Gender { get; set; } } /// /// 映射对象 /// public class StudentViewModel { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } public string Gender { get; set; } }
public class Sample02 { public static void Run() { //映射使用的基本方法 Student 映射源 StudentViewModel映射目标 var config = new MapperConfiguration(cfg => cfg.CreateMap()); var mapper = config.CreateMapper(); var result = GetStudents(); var students = mapper.Map >(result); Print(students); } public static List
GetStudents() { // 通过上下稳 var context = new SampleContext(); return context.Students; } public static void Print(IList studentViewModels) { foreach (var student in studentViewModels) { Console.WriteLine($"Id={student.Id};Name={student.Name};Age={student.Age};Gender={student.Gender}"); } } }
有结构的类型映射(扁平化映射)
////// 源数据1 /// public class User { public int Id { get; set; } public string Name { get; set; } public Address Address { get; set; } } /// ///源数据2 /// public class Address { public string City { get; set; } public string State { get; set; } public string Country { get; set; } } /// /// 视图模型 (目标模型) /// public class UserViewModel { public int Id { get; set; } public string Name { get; set; } public string City { get; set; } public string State { get; set; } public string Country { get; set; } }
public class Sample03 { public static void Run() { var config = new MapperConfiguration(cfg => { cfg.CreateMap() .ForMember( model => model.City,//指定的目标 expression => expression.MapFrom(user => user.Address.City))//指定源 .ForMember( model => model.Country, expression => expression.MapFrom(user => user.Address.Country)) .ForMember( model => model.State, expression => expression.MapFrom(user => user.Address.State)); }); var mapper = config.CreateMapper(); var result = GetUsers(); var users = mapper.Map >(result); Print(users); } public static List
GetUsers() { var context = new SampleContext(); return context.Users; } public static void Print(IList userViewModels) { foreach (var user in userViewModels) { Console.WriteLine($"Id={user.Id};Name={user.Name};City={user.City}"); } } }
如果扁平化映射配置很多 如何方便管理:
使用Profile
public class UserProfile : Profile { public UserProfile() { CreateMap() .ForMember( model => model.City, expression => expression.MapFrom(user => user.Address.City)) .ForMember( model => model.State, expression => expression.MapFrom(user => user.Address.State)) .ForMember( model => model.Country, expression => expression.MapFrom(user => user.Address.Country)); } } public class StudentProfile : Profile { public StudentProfile() { CreateMap (); } }
public class Sample04 { public static void Run() { var config = new MapperConfiguration(cfg => { //只需要添加这个配置对象就可以了 cfg.AddProfile(); cfg.AddProfile (); //还可以使用扫描的方式 //cfg.AddMaps(Assembly.GetExecutingAssembly()); }); var mapper = config.CreateMapper(); var result = GetUsers(); var users = mapper.Map >(result); Print(users); } public static List
GetUsers() { var context = new SampleContext(); return context.Users; } public static void Print(IList userViewModels) { foreach (var user in userViewModels) { Console.WriteLine($"Id={user.Id};Name={user.Name};City={user.City}"); } } }
最终如何结合到asp.net core 中使用呢?

////// 订单 /// public class Order { public Guid Id { get; set; } public DateTime DateOrder { get; set; } public int Quantity { get; set; } public double Amount { get; set; } public Guid ProductId { get; set; } public Product Product { get; set; } } /// /// 产品 /// public class Product { public Guid Id { get; set; } public string Name { get; set; } }
////// 仓储类 /// public class OrderRepository { private readonly SampleContext _context; public OrderRepository(SampleContext context) { _context = context; } public Order GetById(Guid id) { var order = _context.Orders.FirstOrDefault(o => o.Id == id); order.Product = _context.Products.FirstOrDefault(p => p.Id == order.ProductId); return order; } } /// /// 查询处理器 /// public class GetOrderByIdQueryHandler : IRequestHandler { private readonly OrderRepository _orderRepository; private readonly IMapper _mapper; public GetOrderByIdQueryHandler(OrderRepository orderRepository, IMapper mapper) { _orderRepository = orderRepository; _mapper = mapper; } public Task Handle(GetOrderByIdRequestModel request, CancellationToken cancellationToken) { var order = _orderRepository.GetById(request.OrderId); //这里使用autoMapper var response = _mapper.Map (order); return Task.FromResult(response); } } /// /// Profile /// public class OrderProfile : Profile { public OrderProfile() { CreateMap (); } }
////// 响应模式 /// public class GetOrderByIdResponseModel { public Guid Id { get; set; } public DateTime DateOrder { get; set; } public int Quantity { get; set; } public double Amount { get; set; } //注意这种情况 如果在扁平化映射中这种情况是可以自动映射,是由源数据类的类名和属性命结合的情况,这是AutoMapper的默认约定 public Guid ProductId { get; set; } public string ProductName { get; set; } }
public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { services.AddControllers(); //上下文 services.AddSingleton(); //仓储 services.AddScoped (); //注入AutoMapper服务 参数指定了程序集 会自动获取其中的Profile services.AddAutoMapper(Assembly.GetExecutingAssembly()); services.AddMediatR(Assembly.GetExecutingAssembly()); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } }
AutoMapper 自定义解析映射例子:
////// 源 /// public class Customer { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } } /// /// 映射类视图 /// public class CustomerViewModel { public int Id { get; set; } public string FullName { get; set; } } /// /// 解析类定义 Customer源 CustomerViewModel映射对象(目标 ) string解析后的数据类型 /// public class CustomerResolver : IValueResolver string> { public string Resolve(Customer source, CustomerViewModel destination, string destMember, ResolutionContext context) { return source.FirstName + " " + source.LastName; } }
public class Sample05 { public static void Run() { var config = new MapperConfiguration(cfg => { cfg.CreateMap() .ForMember(model => model.FullName, expression => expression.MapFrom ()); }); var mapper = config.CreateMapper(); var customer = new Customer { Id = 1, FirstName = "Klein", LastName = "Moretti" }; var result = mapper.Map (customer); Console.WriteLine(result.FullName); } }
AutoMapper 自定义类型转换映射 例子:
////// 源类型 /// public class Person { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } } /// /// 目标类型 /// public class PersonViewModel { public int Id { get; set; } public string Name { get; set; } /// /// 类型和源类型不匹配 /// public string Age { get; set; } } /// /// 类型转换器 /// public class StringTypeConverter : ITypeConverter<int, string> { public string Convert(int source, string destination, ResolutionContext context) { return source.ToString(); } }
public class Sample06 { public static void Run() { var config = new MapperConfiguration(cfg => { //先定义转换器 cfg.CreateMap<int, string>().ConvertUsing(); cfg.CreateMap (); }); var mapper = config.CreateMapper(); var person = new Person { Id = 1, Age = 10 }; var result = mapper.Map (person); Console.WriteLine($"{result.Age.GetType()}:Age={result.Age})"); } }
AutoMapper动态类型转换映射 的例子
public class Sample07 { public static void Run() { var config = new MapperConfiguration(cfg => {}); var mapper = config.CreateMapper(); var customer = new Customer { Id = 1, FirstName = "Klein", LastName = "Moretti" }; // 强类型对象映射到动态类型对象 var result = mapper.Map<dynamic>(customer); Console.WriteLine($"result:{result.FirstName} {result.LastName}"); // 动态类型对象映射到强类型对象 customer = mapper.Map(result); Console.WriteLine($"customer:{customer.FirstName} {customer.LastName}"); // 字典对象映射到强类型对象 var dict = new Dictionary<string, object> {{"FirstName", "Klein"}, {"LastName", "Moretti"}}; customer = mapper.Map (dict); Console.WriteLine($"dictToCustomer:{customer.FirstName} {customer.LastName}"); } }