我想在映射深度(即级别> 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。我的映射配置出了什么问题?
答案 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时摆脱第一个空格!)。