我已经建立了一个简单的测试用例;这是我的类型:
public class FullCompanyInfo {
public int Id { get; set; }
public string Name { get; set; }
public string Foo { get; set; }
public string Bar { get; set; }
public FullCompanyInfo Parent { get; set; }
}
public class CompanyInChainDTO
{
public int Id { get; set; }
public string Name { get; set; }
public CompanyInChainDTO Parent { get; set; }
}
这是我的映射配置:
cfg.CreateMap<FullCompanyInfo, CompanyInChainDTO>()
.ForMember(dto => dto.Parent, opt =>
{
// Stop recursive parent mapping when name is 33
opt.Condition(comp => {
return comp.Name != "33";
});
});
现在,我将原始对象图设置为映射,映射它并显示JSON结果:
FullCompanyInfo comp = new FullCompanyInfo
{ Id = 1, Name = "11", Foo = "Foo1", Bar = "Bar1", Parent = new FullCompanyInfo
{ Id = 2, Name = "22", Foo = "Foo2", Bar = "Bar2", Parent = new FullCompanyInfo
{ Id = 3, Name = "33", Foo = "Foo3", Bar = "Bar3", Parent = new FullCompanyInfo {
Id = 4, Name = "44", Foo = "Foo4", Bar = "Bar4", Parent = null }
}
}
};
CompanyInChainDTO compChain = _mapper.Map<CompanyInChainDTO>(comp);
var jsonResult = JsonConvert.SerializeObject(compChain);
结果是:
{
"Id": 1,
"Name": "11",
"Parent": {
"Id": 2,
"Name": "22",
"Parent": {
"Id": 3,
"Name": "33",
"Parent": null
}
}
}
到目前为止看来,Parent
的映射在Name
为33时停止了。但是,当我在opt.Condition
调试return comp.Name != "33";
lambda时,我发现AutoMapper按以下顺序传递原始FullCompanyInfo
对象:
Id: 44
Id: 33
Id: 22
Id: 11
因此,即使44
从未进入最终映射,它也正在访问所有4个对象!就像Automapper完全探索对象图,然后在我的Condition
返回false时删除属性一样。为什么不先调用11
的lambda,依此类推,为什么只告诉FullCompanyInfo
子对象映射成员,才加载它呢?
问题在于,在这些环境不仅仅是内存中的实体,而是需要花费时间和资源才能访问的实体的情况下,AutoMapper会访问不需要的内容,而不仅仅是在{{ 1}}告诉它不要映射引用的实体。
答案 0 :(得分:3)
3个字母:Pre
。
不敢相信我在此上浪费了很多时间;我需要改用opt.PreCondition(...)
。告诉您不要访问源成员,实际上它会停止访问。