AutoMapper 11.0.1:如何基于对象内置文化自动映射40个属性?
自动化解决方案
方案1:批量匹配Cost属性(推荐)
利用AutoMapper的ForAllPropertyMaps方法,批量筛选符合名称和类型规则的属性,统一应用解析器:
CreateMap<MyEntity, MyDto>() .ForAllPropertyMaps( // 筛选条件:名称以Cost开头、源类型decimal、目标类型string map => map.SourceMember.Name.StartsWith("Cost") && map.SourceType == typeof(decimal) && map.DestinationType == typeof(string), // 为匹配到的属性应用自定义解析器 (map, opts) => opts.MapFrom<LangResolver>() );
该配置会自动识别所有符合规则的Cost属性,无需逐个编写ForMember配置,完全替代手动重复代码。
方案2:简化筛选条件(可选)
如果实体和DTO的Cost属性命名严格对应,也可以简化筛选条件,只通过名称匹配:
CreateMap<MyEntity, MyDto>() .ForAllPropertyMaps( map => map.SourceMember.Name.StartsWith("Cost"), (map, opts) => opts.MapFrom<LangResolver>() );
方案3:上下文传递语言(灵活扩展)
如果需要在映射时动态传递语言信息(而非依赖源对象属性),可以通过ResolutionContext.Items传递:
// 修改解析器,支持从上下文读取语言 public class LangResolver : IMemberValueResolver<MyEntity, MyDto, decimal, string> { public string Resolve(MyEntity source, MyDto destination, decimal sourceMember, string destMember, ResolutionContext context) { // 优先从上下文读取,否则使用源对象的语言 var language = context.Items.TryGetValue("CustomerLanguage", out var lang) ? (int)lang : source.CustomerLanguage; var cost = decimal.Round(sourceMember, 2, MidpointRounding.AwayFromZero); return language == 2 ? $"{cost.ToString(CultureInfo.GetCultureInfo("fr-CA"))}$" : $"${cost.ToString(CultureInfo.GetCultureInfo("en-CA"))}"; } } // 映射配置保持批量匹配 CreateMap<MyEntity, MyDto>() .ForAllPropertyMaps( map => map.SourceMember.Name.StartsWith("Cost"), (map, opts) => opts.MapFrom<LangResolver>() ); // 调用时可手动传入语言 var data = _mapper.Map<MyDto>(someEntity, opt => opt.Items["CustomerLanguage"] = 2); // 强制使用法语规则
内容的提问来源于stack exchange,提问作者Jeramy Rutley
相关产品推荐
相关产品推荐

