Automapper中ProjectTo与泛型结合时AfterMap不生效问题
问题原因及解决方案
原因
ProjectTo 和 _mapper.Map 的执行逻辑完全不同:
_mapper.Map是内存内映射:先从数据库加载完整的实体对象到内存,再在内存中将实体转换为DTO,AfterMap作为映射完成后的内存操作,会被正常触发。ProjectTo是LINQ投影转换:它会把Automapper的映射规则翻译成SQL语句,直接让数据库返回符合DTO结构的数据,全程不会在内存中创建实体对象,自然也不会执行AfterMap这种需要实体实例存在的内存操作。
解决方案
根据你的需求,有几种可行的处理方式:
1. 用MapFrom替代AfterMap(推荐)
如果AfterMap里是给DTO字段设置固定值或者可通过表达式计算的值,直接用MapFrom配置,这样ProjectTo能识别并转换成SQL投影:
CreateMap<ChecklistSoftwareFirmware, OutputDTO>() .ForMember(dto => dto.ETag, opt => opt.MapFrom(_ => "something here")) .ForMember(dto => dto.Compiler, opt => opt.MapFrom(_ => new Compiler { Name = "foo", Version = "bar" }));
2. 使用AfterProjection(Automapper 9.0+支持)
如果你需要在投影完成后执行内存操作,可以用AfterProjection替代AfterMap,它专门针对ProjectTo场景:
CreateMap<ChecklistSoftwareFirmware, OutputDTO>() .AfterProjection((entity, dto) => { dto.ETag = "something here"; dto.Compiler = new() { Name = "foo", Version = "bar" }; });
3. 保留先查实体再映射的方式
如果业务逻辑必须依赖实体对象的完整数据,或者无法用上述两种方式替换,那就继续使用先查询实体再调用_mapper.Map的方式,确保AfterMap逻辑正常执行。
内容的提问来源于stack exchange,提问作者Gargoyle
相关产品推荐
相关产品推荐

