为什么在AutoMapper中会发生意外映射?

Iva*_*kov 5 c# inheritance automapper

我有一个使用AutoMapper 3.1.1的项目,我能够隔离我遇到的问题.

这是我的测试类:

class BaseClass
{
    public string PropertyA { get; set; }
}

class DerivedClass: BaseClass
{
    public string PropertyB { get; set; }
}

class ContainerClass
{
    public DerivedClass ComplexProperty { get; set; }
    public string PropertyC { get; set; }
}

class SourceClass
{
    public string PropertyA { get; set; }
    public string PropertyB { get; set; }
    public string PropertyC { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

这是我的映射规则:

Mapper.CreateMap<SourceClass, ContainerClass>()
    .ForMember(d => d.ComplexProperty, o => o.MapFrom(s => Mapper.Map<DerivedClass>(s)))
    .AfterMap((s, d) => System.Diagnostics.Debug.WriteLine("SourceClass-> ContainerClass mapped"));

Mapper.CreateMap<SourceClass, DerivedClass>()
    .AfterMap((s, d) => System.Diagnostics.Debug.WriteLine("SourceClass -> DerivedClass mapped"));

Mapper.CreateMap<BaseClass, DerivedClass>()
    .AfterMap((s, d) => System.Diagnostics.Debug.WriteLine("BaseClass -> DerivedClass mapped"));
Run Code Online (Sandbox Code Playgroud)

这是我的代码:

var source = new SourceClass {
    PropertyA = "ValueA",
    PropertyB = "ValueB",
    PropertyC = "ValueC",
};

var destination = Mapper.Map<ContainerClass>(source);

Console.WriteLine("PropertyA: " + destination?.ComplexProperty?.PropertyA);
Console.WriteLine("PropertyB: " + destination?.ComplexProperty?.PropertyB);
Console.WriteLine("PropertyC: " + destination?.PropertyC);
Run Code Online (Sandbox Code Playgroud)

输出是:

PropertyA: ValueA
PropertyB:
PropertyC: ValueC
Run Code Online (Sandbox Code Playgroud)

我希望PropertyB具有"ValueB"的值,但它的值为null.它发生了,因为从BaseClass到DerivedClass的mapper由于某种原因而执行.我的调试输出如下:

SourceClass -> DerivedClass mapped
BaseClass -> DerivedClass mapped
SourceClass -> ContainerClass mapped
Run Code Online (Sandbox Code Playgroud)

为什么AutoMapper执行BaseClass - > DerivedClass映射?


更新:感谢Marius我现在知道从BaseClass到DerivedClass的映射是无效的.我不能像他建议的那样删除这个映射规则,因为我需要它用于我的应用程序.例外情况表明我为PropertyB添加了Ignore:

Mapper.CreateMap<BaseClass, DerivedClass>()
    .ForMember(d => d.PropertyB, o => o.Ignore())
    .AfterMap((s, d) => System.Diagnostics.Debug.WriteLine("BaseClass -> DerivedClass mapped"));
Run Code Online (Sandbox Code Playgroud)

现在Mapper.AssertConfigurationIsValid();不再抛出异常了.但最初的问题仍然存在.为什么AutoMapper执行BaseClass - > DerivedClass映射?

Mar*_*ius 1

在调试 AutoMapper 问题时,我建议通过调用来验证配置,Mapper.AssertConfigurationIsValid();我将其添加到您的代码中,并且收到以下异常消息:

错误消息:AutoMapper.AutoMapperConfigurationException:找到未映射的成员。查看下面的类型和成员。添加自定义映射表达式、忽略、添加自定义解析器或修改源/目标类型

===================================

BaseClass -> DerivedClass(目标成员列表) src.BaseClass -> src.DerivedClass(目标成员列表)

物业B

您可以通过删除 的映射来解决该问题BaseClass -> DerivedClass。然后对的调用也Mapper.AssertConfigurationIsValid();不再抛出。