如何在AutoMapper Profile中基于AfterMap传入值实现条件映射
解决AutoMapper基于传入语言值的条件映射问题
你当前的Profile代码无法正确获取映射时传入的语言值,因为x.language并没有关联到映射上下文的参数。以下是正确的实现方式:
1. 修改Map调用代码,传递语言参数到映射上下文
不要通过AfterMap传递语言值,而是用AutoMapper的Items字典将参数存入映射上下文,这样在Profile配置中可以直接获取:
var provinces = await _repository.AsQueryable().ToListAsync(); var result = provinces.Select(item => _mapper.Map<GetProvincesDto>(item, opt => opt.Items["Language"] = "en")).ToList();
2. 调整Profile配置,通过上下文获取参数实现条件映射
在MapFrom方法中,通过ResolutionContext参数取出存入的语言值,再进行条件判断映射:
public class ProvinceToGetProvincesDto : Profile { public ProvinceToGetProvincesDto() { CreateMap<Province, GetProvincesDto>() .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id)) .ForMember(dest => dest.Name, opt => opt.MapFrom((src, _, __, context) => { // 获取语言参数,默认值设为非英文的情况 var targetLang = context.Items["Language"]?.ToString() ?? ""; return targetLang.Equals("en", StringComparison.OrdinalIgnoreCase) ? src.EnglishName.Value : src.Name.Value; })) // 如果需要给Dto的Language字段赋值,可在此添加AfterMap逻辑 .AfterMap((src, dest, context) => { dest.Language = context.Items["Language"]?.ToString() ?? ""; }); } }
关键说明
- 映射
Name字段时,AfterMap是在核心映射完成后执行的,所以无法提前获取到dest.Language的值,必须通过Items将参数提前传入上下文。 - 添加
StringComparison.OrdinalIgnoreCase可以避免大小写匹配问题,也可根据需求移除。 - 如果存在批量映射场景(如
ProjectTo),同样可以通过ProjectTo的选项设置Items来传递语言参数。
内容的提问来源于stack exchange,提问作者Yaser Nouri
相关产品推荐
相关产品推荐

