为什么我不告诉AutoMapper访问属性?

时间:2018-07-13 16:04:43

标签: c# automapper

我已经建立了一个简单的测试用例;这是我的类型:

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}}告诉它不要映射引用的实体。

1 个答案:

答案 0 :(得分:3)

3个字母:Pre

不敢相信我在此上浪费了很多时间;我需要改用opt.PreCondition(...)。告诉您不要访问源成员,实际上它会停止访问。