在.NET 4.6.2中用AutoMapper 6.1.1实现XmlOrder到Order映射的问题
兼容AutoMapper 6.1.1的XmlOrder到Order映射实现
类结构与映射需求
源类型结构
public class XmlOrder { public OrderType OrderType { get; set; } public object Item { get; set; } } public class XmlTransport { public XmlTransportElement Delivery { get; set; } public XmlTransportElement Pickup { get; set; } } // XmlTransportElement 类结构略
映射规则:
- 当
XmlOrder.OrderType为OrderType.Service时,Item是XmlTransportElement类型,映射后Order.TransportElements包含1个元素 - 当
XmlOrder.OrderType为OrderType.Transport时,Item是XmlTransport类型,映射后Order.TransportElements包含Delivery和Pickup两个非null元素
目标类型结构
public class Order : IOrder { public ITransportElement[] TransportElements { get; set; } } // TransportElement 类结构略
旧版本兼容问题
新版AutoMapper中带context参数的MapFrom写法在6.1.1版本不支持,直接调用静态Mapper.Map的ResolveUsing实现会抛出AutoMapperMappingException,原因是静态Mapper在Profile配置阶段可能未完成初始化,且无法获取当前映射上下文。
正确实现方案
在AutoMapper 6.1.1中,需使用带ResolutionContext参数的ResolveUsing重载,通过上下文获取当前IMapper实例执行子映射,同时修正类型判断错误:
public class OrderProfile : Profile { public OrderProfile() { // 配置XmlTransportElement到TransportElement的基础映射 CreateMap<XmlTransportElement, TransportElement>() // 补充你的额外映射逻辑 ; // 配置XmlOrder到IOrder的映射 CreateMap<XmlOrder, IOrder>() .ConstructUsing(src => new Order()) .ForMember(dest => dest.TransportElements, opt => opt.ResolveUsing((src, dest, context) => { // 判断Item是否为XmlTransport类型 var xmlTransport = src.Item as XmlTransport; if (xmlTransport != null) { var elements = new List<TransportElement>(); // 仅添加非null的Delivery元素 if (xmlTransport.Delivery != null) { elements.Add(context.Mapper.Map<TransportElement>(xmlTransport.Delivery)); } // 仅添加非null的Pickup元素 if (xmlTransport.Pickup != null) { elements.Add(context.Mapper.Map<TransportElement>(xmlTransport.Pickup)); } return elements.ToArray(); } // 处理Item为XmlTransportElement的情况 var xmlElement = src.Item as XmlTransportElement; return xmlElement != null ? new[] { context.Mapper.Map<TransportElement>(xmlElement) } : Array.Empty<TransportElement>(); })); } }
关键改进点
- 使用带
ResolutionContext的ResolveUsing重载,通过context.Mapper获取当前上下文的IMapper实例,避免静态Mapper的初始化问题 - 修正类型判断错误:将原代码中的
Transport改为XmlTransport - 用
List<TransportElement>动态收集非null元素,避免数组中出现空值(若需保留null元素,可沿用原数组写法) - 增加空值判断,防止类型转换异常
内容的提问来源于stack exchange,提问作者GasPanic
相关产品推荐
相关产品推荐

