.NET 5升级后AutoMapper ProjectTo查询性能异常问题咨询
根因定位
你的问题定位完全准确,性能瓶颈确实来自VisualCodeType到VisualCodeTypeDTO的映射规则。
出现性能劣化的核心原因是:
ProjectTo会把AutoMapper的映射规则直接翻译成EF Core的SQL查询逻辑,你原始的映射规则中,Icon字段需要从VisualCodeType反向遍历它关联的所有VisualCode集合,再遍历每个VisualCode关联的Symbols集合才能拿到第一个图片地址- .NET 5对应的EF Core 5版本对这类多层嵌套的反向集合查询的翻译逻辑发生了变化,会生成大量子查询甚至N+1查询,数据量较大时查询耗时会出现指数级上升
- 你切换到手动映射时,是先把
VisualCode及其关联的Doctor/VisualCodeType/Symbols数据一次性加载到内存再做映射,不需要执行额外的反向关联查询,因此性能回归正常
优化方案
你选择的在VisualCodeType表冗余存储Icon字段的方案是非常合理的,适合这类读取频率远高于写入频率的字段,能彻底避免查询时的动态计算开销。如果不想修改表结构,也可以选择以下优化方案:
方案1:调整映射逻辑,避免反向关联查询
把Icon字段的计算逻辑移到VisualCode到VisualCodeDTO的映射规则中,不需要依赖VisualCodeType的反向集合关联:
CreateMap<VisualCode, VisualCodeDTO>() // 原有其他映射规则保持不变 .ForMember(dest => dest.VisualCodeTypeIcon, opt => opt.MapFrom(src => src.VisualCodeType != null && src.VisualCodeType.VisualCodes.Any() && src.VisualCodeType.VisualCodes.First().Symbols.Any() ? src.VisualCodeType.VisualCodes.First().Symbols.First().ImgSrc : string.Empty)); // 移除VisualCodeType映射中的Icon字段规则 CreateMap<VisualCodeType, VisualCodeTypeDTO>();
方案2:开启显式扩展,避免AutoMapper自动加载不必要关联
在调用ProjectTo时开启explicitExpansion配置,手动指定需要映射的字段,避免AutoMapper自动解析所有关联规则:
return await visualCodes.AsNoTracking() .OrderByDescending(x => x.LastUpdated) .ProjectTo<VisualCodeDTO>( _mapper.ConfigurationProvider, explicitExpansion: true, membersToExpand: new Expression<Func<VisualCodeDTO, object>>[] { d => d.DoctorName, d => d.VisualCodeType, d => d.Symbols, d => d.VisualCodeTypeIcon }) .ToListAsync();
内容的提问来源于stack exchange,提问作者roonz11
相关产品推荐
相关产品推荐

