/// 映射的时候一定要保证目标对象的属性是可写的,要不该属性没有效果。
/// 1:扁平化映射
/// 规则:将一个复杂的多层次对象转化为一个单层对象
/// 1:如果有相同属性,则对相同属性进行映射
/// 2:如果没有同名的属性,
/// 则检查同名的方法,
/// 再再检查是否有Get开头的同名方法
/// 然后将 目标对象的属性 按照Pascal规则对属性进行分割,去映射属性
/// 并且每个单词之间还可以组合,就是属性是多个单词页能识别。
/// 属性的类型不会影响优先级关系。
/// 2:映射功能测试
/// 在属性的名字或者是属性的类型不一致的情况下,可以使用映射功能,
/// MapFrom为目标对象设置值
/// 3:映射验证
/// 检查是否所有的目标属性都有对应的映射以及类型是否一致。
/// 4:集合的映射
/// 只需要对元素进行配置就可以了,
/// IEnumerable,IEnumerable<T>,ICollection,ICollection<T>,IList,IList<T>,List<T>,Arrays
/// 都默认支持
/// 5:嵌套映射
/// 可以将一个复杂对象映射为另外的一个复杂对象
/// 6:自定义类型转换器
/// 在全局范围内,将一种类型转换为另外的一种类型
/// 比如讲string 转换为时间,将string 转换为类对象,或者将类对象转换为string等
/// 7:自定义属性值映射器
/// 主要是解决值需要通过一个函数计算来获得的情况,
/// 鸡肋功能,可以用MapFrom替代
/// 8:空值的处理
/// 当源对象为空时,目标对象的处理办法
/// 9:继承关系的映射处理
/// 继承的优先级别是:
/// a:类本身的直接映射MapFrom
/// b:继承的直接映射MapFrom
/// c:本身的Ignore映射
/// d:默认规则映射
/// e:继承的Ignore映射
/// 需要注意的是 NullSubstitute没有被继承下来,需要在子类里接着写
/// 10:条件映射处理Condition
/// 当满足条件时才能进行映射处理
/// 11:创建动态映射
/// 当源数据类型不是那么严格时,可以使用动态映射DynamicMap
定义数据结构:
#region 数据库结构信息 public class CustomerInfo : ModelBase { private Guid id = Guid.Empty; public Guid Id { get { return id; } set { id = value; } } private string name = string.Empty; public string Name { get { return name; } set { name = value; } } private List<OrderInfo> orders = new List<OrderInfo>(); public List<OrderInfo> Orders { get { return orders; } set { orders = value; } } public int OrderCount { get { if (orders == null) { return 0; } return orders.Count; } } public OrderInfo MainOrder { get { if (orders.Count > 0) { return orders[0]; } return null; } } public int GetName() { return 100; } } public class OrderInfo : ModelBase { private string name = ""; public string Name { get { return name; } set { name = value; } } private DateTime createDate = DateTime.Now; public DateTime CreateDate { get { return createDate; } set { createDate = value; } } private PaymentInfo payment = null; public PaymentInfo Payment { get { return payment; } set { payment = value; } } private Guid customerId = Guid.Empty; public Guid CustomerId { get { return customerId; } set { customerId = value; } } private Guid id = Guid.Empty; public Guid Id { get { return id; } set { id = value; } } private CustomerInfo customer = null; public CustomerInfo Customer { get { return customer; } set { customer = value; } } private List<OrderItemInfo> orderItems = new List<OrderItemInfo>(); public List<OrderItemInfo> OrderItems { get { return orderItems; } set { orderItems = value; } } public int GetItemsCount() { if (orderItems == null) { return 0; } return orderItems.Count; } public string SameProperty1 { get { return "相同属性"; } } public string GetSameProperty1() { return "方法——相同属性"; } public int SameProperty2 { get { return 222; } } public string GetSameProperty2() { return "方法——222相同属性"; } public string SameProperty3 { get { return "222"; } } public int GetSameProperty3() { return 222; } } public class TelephoneOrderInfo : OrderInfo { private string telephone = ""; public string Telephone { get { return telephone; } set { telephone = value; } } } public class WeixinOrderInfo : OrderInfo { private string openId = ""; public string OpenId { get { return openId; } set { openId = value; } } } public class OrderItemInfo : ModelBase { private Guid id = Guid.Empty; public Guid Id { get { return id; } set { id = value; } } private int count = 0; public int Count { get { return count; } set { count = value; } } private OrderInfo order = null; public OrderInfo Order { get { return order; } set { order = value; } } private Guid goodsId = Guid.Empty; public Guid GoodsId { get { return goodsId; } set { goodsId = value; } } private GoodsInfo goods = null; public GoodsInfo Goods { get { return goods; } set { goods = value; } } } public class GoodsInfo : ModelBase { private Guid id = Guid.Empty; public Guid Id { get { return id; } set { id = value; } } private string name = string.Empty; public string Name { get { return name; } set { name = value; } } private decimal price = 0; public decimal Price { get { return price; } set { price = value; } } private int goodsType = 0; public int GoodsType { get { return goodsType; } set { goodsType = value; } } } public class PaymentInfo : ModelBase { private Guid id = Guid.Empty; public Guid Id { get { return id; } set { id = value; } } private DateTime payDate = DateTime.MinValue; public DateTime PayDate { get { return payDate; } set { payDate = value; } } } #endregion 数据库结构信息 #region 前端展现信息 public class CustomerInfoVModel : ModelBase { private Guid id = Guid.Empty; public Guid Id { get { return id; } set { id = value; } } private string name = string.Empty; public string Name { get { return name; } set { name = value; } } private int orderCount = 0; public int OrderCount { get { return orderCount; } set { orderCount = value; } } } public class OrderInfoVModel : ModelBase { private string payment = string.Empty; public string Payment { get { return payment; } set { payment = value; } } private CustomerInfoVModel customer2; public CustomerInfoVModel Customer2 { get { return customer2; } set { customer2 = value; } } private string customerMainOrderSameProperty1 = ""; public string CustomerMainOrderSameProperty1 { get { return customerMainOrderSameProperty1; } set { customerMainOrderSameProperty1 = value; } } private int customerMainOrderSameProperty2 = 0; public int CustomerMainOrderSameProperty2 { get { return customerMainOrderSameProperty2; } set { customerMainOrderSameProperty2 = value; } } private int customerMainOrderSameProperty3 = 0; public int CustomerMainOrderSameProperty3 { get { return customerMainOrderSameProperty3; } set { customerMainOrderSameProperty3 = value; } } private string customerMainOrderName = ""; public string CustomerMainOrderName { get { return customerMainOrderName; } set { customerMainOrderName = value; } } private DateTime customerMainOrderCreateDate = DateTime.Now; public DateTime CustomerMainOrderCreateDate { get { return customerMainOrderCreateDate; } set { customerMainOrderCreateDate = value; } } private decimal totalAmount = 0; public decimal TotalAmount { get { return totalAmount; } set { totalAmount = value; } } private DateTime createDate = DateTime.Now; public DateTime CreateDate { get { return createDate; } set { createDate = value; } } private string customerName = ""; public string CustomerName { get { return customerName; } set { customerName = value; } } private int customerOrderCount = 0; public int CustomerOrderCount { get { return customerOrderCount; } set { customerOrderCount = value; } } private int itemsCount = 0; public int ItemsCount { get { return itemsCount; } set { itemsCount = value; } } private string yearMonth = ""; public string YearMonth { get { return yearMonth; } set { yearMonth = value; } } List<string> orderItemDescs = new List<string>(); public List<string> OrderItemDescs { get { return orderItemDescs; } set { orderItemDescs = value; } } } public class OrderItemInfoVModel : ModelBase { private Guid id = Guid.Empty; public Guid Id { get { return id; } set { id = value; } } private int count = 0; public int Count { get { return count; } set { count = value; } } private Guid orderId = Guid.Empty; public Guid OrderId { get { return orderId; } set { orderId = value; } } private string goodsName = ""; public string GoodsName { get { return goodsName; } set { goodsName = value; } } private decimal goodsPrice = 0; public decimal GoodsPrice { get { return goodsPrice; } set { goodsPrice = value; } } private decimal totalAmount = 0; public decimal TotalAmount { get { return totalAmount; } set { totalAmount = value; } } } public class TelephoneOrderInfoVModel : OrderInfoVModel { private string telephone = ""; public string Telephone { get { return telephone; } set { telephone = value; } } } public class WeixinOrderInfoVModel : OrderInfoVModel { private string openId = ""; public string OpenId { get { return openId; } set { openId = value; } } } #endregion 前端展现信息 public class ModelBase { public override string ToString() { List<PropertyInfo> properties = this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).ToList(); StringBuilder sb = new StringBuilder(); properties.ForEach(o => { if ((o.PropertyType.IsValueType || o.PropertyType == typeof(string)) && o.CanRead) { sb.AppendFormat("{0}:{1}{2}", o.Name, o.GetValue(this, null), Environment.NewLine); } }); return sb.ToString(); } }
初始化数据:
public CustomerInfo GetInitialData() { CustomerInfo customerInfo = new CustomerInfo(); customerInfo.Id = Guid.NewGuid(); customerInfo.Name = "zhu"; customerInfo.Orders = new List<OrderInfo>(); Random random = new Random(); List<GoodsInfo> goods = new List<GoodsInfo>(); int goodsCount = random.Next(30) + 10; for (int i = 0; i < goodsCount; i++) { goods.Add(new GoodsInfo() { Id = Guid.NewGuid(), Name = "商品" + i.ToString(), GoodsType = random.Next(5), Price = random.Next(200) + 2 }); } int ordersCount = random.Next(10) + 5; for (int i = 0; i < ordersCount; i++) { if ((i % 2) == 0) { customerInfo.Orders.Add(new TelephoneOrderInfo() { Telephone = "电话号码:" + i.ToString() }); } else { customerInfo.Orders.Add(new WeixinOrderInfo() { OpenId = "微信号:" + i.ToString() }); } } customerInfo.Orders.ForEach(o => { o.Id = Guid.NewGuid(); o.CreateDate = DateTime.Now.AddDays(random.Next(365)); o.Customer = customerInfo; o.CustomerId = customerInfo.Id; o.Name = string.Format("{0}订单{1}", customerInfo.Name, o.CreateDate.ToString("yyyy-MM-dd HH:mm:ss")); o.OrderItems = new List<OrderItemInfo>(); int orderItemsCount = random.Next(5) + 1; for (int i = 0; i < orderItemsCount; i++) { o.OrderItems.Add(new OrderItemInfo() { Count = 1 + random.Next(6), Id = Guid.NewGuid(), Goods = goods[random.Next(goods.Count)] }); o.OrderItems.ForEach(oi => { oi.GoodsId = oi.Goods.Id; oi.Order = o; }); } }); return customerInfo; }
功能测试:
CustomerInfo customerInfo = GetInitialData(); Mapper.CreateMap<string, int>().ConvertUsing(Convert.ToInt32); Mapper.CreateMap<string, DateTime>().ConvertUsing(new DateTimeTypeConverter()); Mapper.CreateMap<OrderItemInfo, string>().ConvertUsing(o => o.ToString().Replace(Environment.NewLine, "---")); Mapper.CreateMap<CustomerInfo, CustomerInfoVModel>(); Mapper.CreateMap<OrderInfo, OrderInfoVModel>() .Include<TelephoneOrderInfo, TelephoneOrderInfoVModel>() .Include<WeixinOrderInfo, WeixinOrderInfoVModel>() .ForMember(o => o.Customer2, d => d.MapFrom(df => df.Customer)) .ForMember(o => o.OrderItemDescs, d => d.MapFrom(df => df.OrderItems)) .ForMember(o => o.Payment, d => d.NullSubstitute("还没有做订单管理")) .ForMember(o => o.YearMonth, d => d.MapFrom(df => df.CreateDate.ToString("yyyyMM"))); Mapper.CreateMap<TelephoneOrderInfo, TelephoneOrderInfoVModel>() .ForMember(o => o.Payment, d => d.NullSubstitute("还没有做订单管理")); Mapper.CreateMap<WeixinOrderInfo, WeixinOrderInfoVModel>() .ForMember(o => o.Payment, d => d.NullSubstitute("还没有做订单管理")); /// Mapper.AssertConfigurationIsValid(); txtMsg.Text = ""; StringBuilder sb = new StringBuilder(); sb.AppendLine("扁平映射"); OrderInfoVModel vModel = Mapper.Map<OrderInfo, OrderInfoVModel>(customerInfo.Orders[3]); sb.AppendLine(vModel.ToString()); sb.AppendLine("嵌套映射"); sb.AppendLine(vModel.Customer2.ToString()); sb.AppendLine("自定义转换器映射"); sb.AppendLine(string.Join(Environment.NewLine, vModel.OrderItemDescs)); sb.AppendLine("空对象处理"); sb.AppendLine(vModel.Payment); var orders = Mapper.Map<List<OrderInfo>, List<OrderInfoVModel>>(customerInfo.Orders); orders.ForEach(o => sb.AppendLine(o.ToString())); DataTable dt = new DataTable(); dt.Columns.Add("Id", typeof(Guid)); dt.Columns.Add("Name"); for (int i = 0; i < 10; i++) { DataRow dr = dt.NewRow(); dr["Id"] = Guid.NewGuid(); dr["Name"] = "姓名" + i.ToString(); dt.Rows.Add(dr); } List<CustomerInfoVModel> customers = Mapper.DynamicMap<List<CustomerInfoVModel>>(dt.CreateDataReader()); sb.AppendLine("DynamicMap动态映射处理"); customers.ForEach(o => sb.AppendLine(o.ToString())); txtMsg.Text = sb.ToString();
映射类
public class DateTimeTypeConverter : ITypeConverter<string, DateTime> { public DateTime Convert(ResolutionContext context) { return System.Convert.ToDateTime(context.SourceValue); } }