2017-06-06 91 views
0

我们刚刚从Automapper 3.3.0升级到6.0.2,在升级我们的解决方案后,其中一个映射似乎不再有效。Automapper - 映射重写属性导致抛出异常

考虑一下:

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 })); 

现在,如果我尝试将“源”对象映射到一个新的“DerivedDestinationMaster”例如,我得到一个例外,说明我无法将“DestinationChild”转换为“DerivedDestinationChild”。

如果我在overriden属性的“setter”访问器中放置了一个断点,我清楚地看到传入的实例的类型是“DestinationChild”。我还可以看到有两个构造函数调用了“DestinactionChild”类。 “GrossAmount”值是来自“Source”对象的良好值,而不是0,就好像在创建“DerivedDestinationChild”实例之后,它会创建一个新的“DestinationChild”实例来接收信息并自动映射这两个对象。我们的场景有点复杂(我们使用IValueResolver),但是我们使用“MapFrom”,“UseValue”和自定义Resolver进行测试,并且在所有情况下,最终实例都不是派生类型。

如果我们在映射把“act.Ignore()”,唯一的例外是没有提出

谢谢您的帮助!

回答

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返回一个特定的派生类型。