.Net Core 常用类库 AutoMapper

1 AutoMapper

同一个数据实体,在不同场合需要转换成不同模式的情况

映射两个对象之间的映射,一般是数据模型映射到视图模型,如果没有AutoMapper 需要手动处理费时费力

 

 包 AutoMapper

 同名部分大小写会自动映射

复制代码
    /// <summary>
     /// 映射源
    /// </summary>
    public class Student
    {
        public int Id { get; set; }

        public string Name { get; set; }

        public int Age { get; set; }

        public string Gender { get; set; }
    }

    /// <summary>
    /// 映射对象
    /// </summary>
    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<Student, StudentViewModel>());
            var mapper = config.CreateMapper();

            var result = GetStudents();          
            var students = mapper.Map<List<StudentViewModel>>(result);
            Print(students);
        }

        public static List<Student> GetStudents()
        {
             // 通过上下稳
            var context = new SampleContext();
            return context.Students;
        }

        public static void Print(IList<StudentViewModel> studentViewModels)
        {
            foreach (var student in studentViewModels)
            {
                Console.WriteLine($"Id={student.Id};Name={student.Name};Age={student.Age};Gender={student.Gender}");
            }
        }
    }
复制代码

有结构的类型映射(扁平化映射)

复制代码
     /// <summary>
    /// 源数据1
    /// </summary>
    public class User
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public Address Address { get; set; }
    }
  
      /// <summary>
     ///源数据2
     /// </summary>
    public class Address
    {
        public string City { get; set; }
        public string State { get; set; }
        public string Country { get; set; }

    }

    /// <summary>
    /// 视图模型 (目标模型)
    /// </summary>
    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<User, UserViewModel>()
                    .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<List<UserViewModel>>(result);
            Print(users);
        }

        public static List<User> GetUsers()
        {
            var context = new SampleContext();
            return context.Users;
        }

        public static void Print(IList<UserViewModel> 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<User, UserViewModel>()
                .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<Student, StudentViewModel>();
        }
    }
复制代码
复制代码
public class Sample04
    {
        public static void Run()
        {
            
            var config = new MapperConfiguration(cfg =>
            {
                //只需要添加这个配置对象就可以了 
                cfg.AddProfile<UserProfile>();
                cfg.AddProfile<StudentProfile>();
                //还可以使用扫描的方式
                //cfg.AddMaps(Assembly.GetExecutingAssembly());
            });

            var mapper = config.CreateMapper();

            var result = GetUsers();
            var users = mapper.Map<List<UserViewModel>>(result);
            Print(users);
        }

        public static List<User> GetUsers()
        {
            var context = new SampleContext();
            return context.Users;
        }

        public static void Print(IList<UserViewModel> userViewModels)
        {
            foreach (var user in userViewModels)
            {
                Console.WriteLine($"Id={user.Id};Name={user.Name};City={user.City}");
            }
        }
    }
复制代码

最终如何结合到asp.net core 中使用呢?

 

 

复制代码
    /// <summary>
    /// 订单
    /// </summary>
    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; }
    }

   /// <summary>
    /// 产品
    /// </summary>
    public class Product
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
    }
复制代码
复制代码
    /// <summary>
    /// 仓储类
    /// </summary>
    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;
        }
    }


    /// <summary>
    /// 查询处理器
    /// </summary>
    public class GetOrderByIdQueryHandler : IRequestHandler<GetOrderByIdRequestModel, GetOrderByIdResponseModel>
    {
        private readonly OrderRepository _orderRepository;
        private readonly IMapper _mapper;

        public GetOrderByIdQueryHandler(OrderRepository orderRepository, IMapper mapper)
        {
            _orderRepository = orderRepository;
            _mapper = mapper;
        }

        public Task<GetOrderByIdResponseModel> Handle(GetOrderByIdRequestModel request, CancellationToken cancellationToken)
        {
            var order = _orderRepository.GetById(request.OrderId);
            //这里使用autoMapper
            var response = _mapper.Map<GetOrderByIdResponseModel>(order);
            return Task.FromResult(response);
        }
    }

   /// <summary>
    /// Profile
    /// </summary>
    public class OrderProfile : Profile
    {
        public OrderProfile()
        {
            CreateMap<Order, GetOrderByIdResponseModel>();
        }
    }
复制代码
复制代码
/// <summary>
    /// 响应模式
    /// </summary>
    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<SampleContext>();
            //仓储
            services.AddScoped<OrderRepository>();
            //注入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 自定义解析映射例子:

复制代码
    /// <summary>
    ////// </summary>
    public class Customer
    {
        public int Id { get; set; }

        public string FirstName { get; set; }

        public string LastName { get; set; }
    }

   /// <summary>
    /// 映射类视图
    /// </summary>
    public class CustomerViewModel
    {
        public int Id { get; set; }

        public string FullName { get; set; }
    }

    /// <summary>
    /// 解析类定义 Customer源 CustomerViewModel映射对象(目标 ) string解析后的数据类型 
    /// </summary>
    public class CustomerResolver : IValueResolver<Customer, CustomerViewModel, 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<Customer, CustomerViewModel>()
                    .ForMember(model => model.FullName, expression => expression.MapFrom<CustomerResolver>());
            });

            var mapper = config.CreateMapper();

            var customer = new Customer
            {
                Id = 1,
                FirstName = "Klein",
                LastName = "Moretti"
            };

            var result = mapper.Map<CustomerViewModel>(customer);
            Console.WriteLine(result.FullName);
        }
    }
复制代码

AutoMapper 自定义类型转换映射 例子:

复制代码
    /// <summary>
    /// 源类型
    /// </summary>
    public class Person
    {
        public int Id { get; set; }

        public string Name { get; set; }

        public int Age { get; set; }
    }

    /// <summary>
    /// 目标类型
    /// </summary>
    public class PersonViewModel
    {
        public int Id { get; set; }

        public string Name { get; set; }
        /// <summary>
        /// 类型和源类型不匹配
        /// </summary>
        public string Age { get; set; }
    }

     /// <summary>
    /// 类型转换器
    /// </summary>
    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<StringTypeConverter>();
                cfg.CreateMap<Person, PersonViewModel>();
            });

            var mapper = config.CreateMapper();

            var person = new Person
            {
                Id = 1,
                Age = 10
            };

            var result = mapper.Map<PersonViewModel>(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<Customer>(result);
            Console.WriteLine($"customer:{customer.FirstName} {customer.LastName}");

            // 字典对象映射到强类型对象
            var dict = new Dictionary<string, object> {{"FirstName", "Klein"}, {"LastName", "Moretti"}};
            customer = mapper.Map<Customer>(dict);
            Console.WriteLine($"dictToCustomer:{customer.FirstName} {customer.LastName}");
        }
    }
复制代码

 

posted @   根仔  阅读(289)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示