Automapper忽略属性的忽略

时间:2011-03-23 06:15:52

标签: automapper

我想在映射深度(即级别> 1)对象模型时忽略某些属性。

以下测试正常:

class Foo
{
    public string Text { get; set; }
}

class Bar
{
    public string Text { get; set; }
}

Mapper.CreateMap<Foo, Bar>()
      .ForMember(x => x.Text, opts => opts.Ignore());

var foo = new Foo { Text = "foo" };
var bar = new Bar { Text = "bar" };
Mapper.Map(foo, bar);
Assert.AreEqual("bar", bar.Text);

但是,当我尝试执行相同的映射但在父类上使用Foo和Bar作为属性时,以下测试失败:

class ParentFoo
{
    public Foo Child { get; set; }
}

class ParentBar
{
    public Bar Child { get; set; }
}

Mapper.CreateMap<ParentFoo, ParentBar>();

Mapper.CreateMap<Foo, Bar>()
      .ForMember(x => x.Text, opts => opts.Ignore());

var parentFoo = new ParentFoo          
{
    Child = new Foo { Text = "foo" }
};

var parentBar = new ParentBar
{
    Child = new Bar { Text = "bar" }
};

Mapper.Map(parentFoo, parentBar);
Assert.AreEqual("bar", parentBar.Child.Text);

而不是忽略Child类的文本(即将其保留为“bar”),automapper将值设置为null。我的映射配置出了什么问题?

1 个答案:

答案 0 :(得分:10)

Automapper有两种方法可以执行映射。第一种方法是简单地为Automapper提供源对象,它将创建一个新的目标对象并为您填充所有内容。这是大多数应用程序使用Automapper的方式。但是,第二种方法是为它提供源和现有目标,Automapper将使用您的映射更新现有目标。

在第一个示例中,您将为其提供现有目标值,因此Automapper将使用该值。在第二个示例中,Automapper将为ParentFoo和ParentBar执行映射,但是当它到达Child时,它将创建一个新的Child,然后执行映射(这是默认行为)。这导致Text属性为null。如果要使用现有的Child对象,则需要配置Automapper以使用UseDestinationValue执行此操作:

Mapper.CreateMap<ParentFoo, ParentBar>()
    .ForMember(b => b.Child, o => o.UseDestinationValue());

这会让你的测试通过(只要你在设置parentBar.Child.Text时摆脱第一个空格!)。