You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 00:05:17