2

我有以下类结构:

public class A
{
    public bool Property1 { get; set; }
    public bool Property2 { get; set; }
}

public class ContainerForA
{
    public A A { get; set; }
}

public class A1
{
    public bool Property1 { get; set; }
}

public class ContainerForA1
{
    public A1 A { get; set; }
}

我为这组类创建了一个映射:

Mapper.CreateMap<A1, A>();
Mapper.CreateMap<ContainerForA1, ContainerForA>();

我创建了这组类的一个实例:

        var cnt_a = new ContainerForA()
                        {
                            A = new A()
                                    {
                                        Property1 = false,
                                        Property2 = true
                                    }
                        };

        var cnt_a1 = new ContainerForA1()
                         {
                             A = new A1()
                                     {
                                         Property1 = true
                                     }
                         };

如果我打电话Mapper.Map(cnt_a1.A, cnt_a.A),我会得到我期望的结果:对象cnt_aProperty1的两个属性 (和)都是trueProperty2

但是,如果我打电话给Mapper.Map(cnt_a1, cnt_a)我,我会得到 true forProperty1和 false for Property2。有人可以解释我为什么吗?是否有任何选择让我以这种方式声明我的映射,这样我就不会丢失目标对象中存在但不在源对象中的属性?

4

1 回答 1

4

我猜想当你映射 from ContainerForA1to时,当映射属性 A 时,它会创建一个forContainerForA的新实例,而不是使用现有的实例。这将使用所有属性的默认值,即.AContainerForAfalsebool

我们如何解决这个问题?

首先,我们需要告诉 AutoMapper 不要覆盖 ContainerForA 上的属性 A。为此,我们将告诉 AutoMapper 忽略该属性。

Mapper.CreateMap<ContainerForA1, ContainerForA>()
    .ForMember(cForA => cForA.A, option => option.Ignore());

现在我们需要手动更新 A,使用 AfterMap

Mapper.CreateMap<ContainerForA1, ContainerForA>()
    .ForMember(cForA => cForA.A, option => option.Ignore())
    .AfterMap((cForA1, cForA) => Mapper.Map(cForA1.A, cForA.A));

您可能希望向 AfterMap 方法添加一些检查,以确保 cForA.A 不为空。我会把它留给你。

于 2012-07-05T15:09:05.680 回答