我们刚刚从Automapper 3.3.0升级到6.0.2,在升级我们的解决方案之后,其中一个映射似乎不再起作用了。
考虑一下:
public class Source{
public Decimal GrossAmount {get;set;}
}
public class DerivedSource : Source{
}
public class DestinationMaster{
public virtual DestinationChild Child {get;set;}
}
public class DestinationChild{
public decimal GrossAmount {get;set;}
}
public class DerivedDestinationMaster : DestinationMaster {
private DerivedDestinationChild _destinationChild;
public override DestinationChild Child {
get{return _destinationChild;}
set{_destinationChild = (DerivedDestinationChild)value;}
}
}
public class DerivedDestinationChild : DestinationChild{
public string OtherProperty {get;set;}
}
现在为映射:
CreateMap<Source,DestinationMaster>()
.Include<DerivedSource,DerivedDestinationMaster>();
CreateMap<DerivedSource,DerivedDestinationMaster>()
.ForMember(dest => dest.Child, act=> act.MapFrom(src => new DerivedDestinationChild(){ GrossAmount = src.GrossAmount }));
现在,如果我尝试将“Source”对象映射到新的“DerivedDestinationMaster”实例,我会得到一个Exception,告诉我无法将“DestinationChild”转换为“DerivedDestinationChild”。
如果我在overriden属性的“setter”访问器中放置一个断点,我清楚地看到传递的实例是“DestinationChild”类型。我还可以看到“DestinactionChild”类有两个构造函数调用。 “GrossAmount”值是来自“Source”对象的好值而不是0,就好像在创建“DerivedDestinationChild”实例之后,它创建了一个新的“DestinationChild”实例来接收信息并自动化这两个对象。
我们的场景有点复杂(我们使用IValueResolver),但我们使用“MapFrom”,“UseValue”和自定义解析器进行测试,并且在所有情况下,最终实例都不是派生类型。
如果我们在映射上放置“act.Ignore()”,则不会引发异常
感谢您的帮助!
答案 0 :(得分:0)
作为文档here,映射遵循继承树的特定顺序。你可以通过复制一些地图来实现它的工作方式,这对你来说是一个可行的解决方案吗?
class Program
{
static void Main(string[] args)
{
Mapper.Initialize(cfg =>
{
cfg.CreateMap<Source, DestinationMaster>().ForMember(dest => dest.Child, act => act.MapFrom(s => new DestinationChild { GrossAmount = s.GrossAmount}));
cfg.CreateMap<DerivedSource, DerivedDestinationMaster>().IncludeBase<Source, DestinationMaster>().ForMember(dest => dest.Child, act => act.MapFrom(s => new DerivedDestinationChild { GrossAmount = s.GrossAmount }));
});
var source = new Source() {GrossAmount = 99};
var destinationMaster = Mapper.Map<DestinationMaster>(source);
Debug.Assert(destinationMaster.Child.GrossAmount == source.GrossAmount);
Debug.Assert(destinationMaster.Child.GetType() == typeof(DestinationChild));
var derivedSource = new DerivedSource() {GrossAmount = 10};
var derivedDestinationMaster = Mapper.Map<DerivedDestinationMaster>(derivedSource);
Debug.Assert(derivedDestinationMaster.Child.GrossAmount == derivedSource.GrossAmount);
Debug.Assert(derivedDestinationMaster.Child.GetType() == typeof(DerivedDestinationChild));
}
}
除此之外,我不确定如何使用从基本映射映射的GrossAmount
返回特定的派生类型。