为何AutoMapper会加载已被忽略的NHibernate延迟加载属性?
原因分析
AutoMapper默认会遍历源对象的所有公共属性,哪怕你已经配置忽略目标DTO的对应属性。由于Foo.Bars是ORM的延迟加载虚拟属性,当AutoMapper访问它的getter时,ORM会自动触发数据库查询加载关联数据——这就是你看到SQL执行的原因,而因为目标属性被忽略,这些数据最终不会映射到DTO里。
解决办法
要避免这种情况,你需要在映射配置里同时告诉AutoMapper不要处理源对象的Bars属性,而不只是忽略目标成员:
CreateMap<Foo, FooDTO>() .ForMember(dest => dest.Bars, opt => opt.Ignore()) .ForSourceMember(src => src.Bars, opt => opt.DoNotValidate());
在AutoMapper较新版本中,也可以直接用ForSourceMember的Ignore配置:
CreateMap<Foo, FooDTO>() .ForMember(dest => dest.Bars, opt => opt.Ignore()) .ForSourceMember(src => src.Bars, opt => opt.Ignore());
这样配置后,AutoMapper会完全跳过对Foo.Bars的访问,自然不会触发ORM的延迟加载。
另外,如果你用的是EF这类ORM,也可以在查询Foo时,通过Select明确只取需要的字段(比如仅Name),从根源上避免关联数据被加载:
var foo = dbContext.Foos.Select(f => new { f.Name }).FirstOrDefault(); // 后续直接映射匿名对象到FooDTO,或者直接构造DTO实例
内容的提问来源于stack exchange,提问作者Shing
相关产品推荐
相关产品推荐

