我的类
XmlOrder
包含两个属性
public class XmlOrder
{
public OrderType OrderType { get; set; }
public object Item { get; set; }
}
如果
OrderType
等于 OrderType.Service,则 Item
将是 XmlTransportElement
类型。如果是 OrderType.Transport,则其类型为 XmlTransport
。 XmlTransport
有以下两个性质:
public class XmlTransport
{
public XmlTransportElement Delivery { get; set; }
public XmlTransportElement Pickup { get; set; }
}
XmlOrder
需要映射到 Order
,如下所示:
public class Order : IOrder
{
public ITransportElement[] TransportElements { get; set; }
}
根据上述逻辑,该数组将具有一个或两个条目。
在我的示例项目中,我使用最新的 AutoMapper 版本编写了此代码,并且运行良好:
public class OrderProfile : Profile
{
public OrderProfile()
{
// Mapping for XmlOrder to IOrder
CreateMap<XmlOrder, IOrder>()
.ConstructUsing(src => new Order())
.ForMember(dest => dest.TransportElements, opt => opt.MapFrom((src, dest, _, context) =>
src.Item is XmlTransport transport
? new[]
{
transport.Delivery != null ? context.Mapper.Map<TransportElement>(transport.Delivery) : null,
transport.Pickup != null ? context.Mapper.Map<TransportElement>(transport.Pickup) : null
}
: new[] { context.Mapper.Map<TransportElement>((XmlTransportElement)src.Item) }
));
// Mapping for XmlTransportElement to TransportElement
CreateMap<XmlTransportElement, TransportElement>()
// additional logic
}
}
问题是,我需要使用 AutoMapper 6.1.1 在旧应用程序中实现此功能。上面的代码不起作用,因为
.MapFrom
在旧版本中不能像这样使用。我已经绕了两天,尝试了使用 .ConvertUsing
和 .ResolveUsing
与自定义转换器结合使用的各种方法,但总是遇到 NullReferenceExceptions 或其他错误。
我尝试过的最新方法是这个,它会抛出 AutoMapperMappingException:
CreateMap<XmlOrder, IOrder>()
.ForMember(dest => dest.TransportElements, opt => opt.ResolveUsing(src =>
{
var transport = src.Item as Transport;
if (transport != null)
{
return new[]
{
transport.Delivery != null ? Mapper.Map<TransportElement>(transport.Delivery) : null,
transport.Pickup != null ? Mapper.Map<TransportElement>(transport.Pickup) : null
};
}
return new[] { Mapper.Map<TransportElement>((XmlTransportElement)src.Item) };
}))
.ConstructUsing(src => new Order());
如有任何帮助,我们将不胜感激。 AI 根本没有帮助,并且不断提出不适用于此特定 AutoMapper 版本的建议。
最终找到了解决方案。
CreateMap<XmlOrder, IOrder>( )
.ConstructUsing(src => new SharedOrderForPool( ))
.ForMember(dest => dest.TransportElements, opt => opt.ResolveUsing(src => {
switch (src.Item)
{
case XmlTransport xmltransport:
{
var elements = new List<TransportElement>( );
if ( transport.Delivery != null ) {
elements.Add(new TransportElement {
// additional logic
});
}
if ( transport.Pickup != null ) {
elements.Add(new TransportElement {
// additional logic
});
}
return elements.ToArray( );
}
case XmlTransportElement xmlTransportElement:
return new[]
{
new TransportElement
{
// additional logic
};
default:
return null;
}
}));