升级AutoMapper至11.0.0后List转Dictionary映射报错问题
AutoMapper 11.0.0 升级后 List 转 Dictionary 映射失败问题解决(原10.1.1版本正常)
我帮你排查了这个问题,核心原因是AutoMapper 11版本引入了更严格的集合映射规则,并且默认开启了严格映射模式(Strict Mapping Mode),这和10.x版本的处理逻辑有明显差异。
问题根源
在10.1.1版本中,你用MapFrom把ProcessRoles集合转成Dictionary的自定义投影,AutoMapper会直接忽略默认的集合映射逻辑,优先执行你的代码。但到了11.0.0版本:
- 当目标成员是
Dictionary<TKey, TValue>类型时,AutoMapper会先尝试用默认的集合映射逻辑去处理,这就和你自定义的ToDictionary投影产生了冲突; - 默认开启的严格映射模式会检测到源集合类型和目标字典类型不匹配,直接抛出映射错误。
解决方案1:用ConvertUsing替代MapFrom(推荐)
这个方法可以完全绕过AutoMapper的默认集合映射逻辑,直接使用你的自定义投影,和10.x版本的行为一致:
CreateMap<ProcessActorEntity, ProcessActorViewModel>() .ForMember(dest => dest.Roles, opt => opt.ConvertUsing(src => src.ProcessRoles.ToDictionary(x => x.Role.Id, x => x.Role.Title)));
解决方案2:全局关闭严格映射模式(不推荐)
如果你有很多类似的映射不想逐个修改,可以在初始化AutoMapper时全局关闭严格模式,但这样会失去该模式带来的错误检测能力,不建议长期使用:
var configuration = new MapperConfiguration(cfg => { cfg.CreateMap<ProcessActorEntity, ProcessActorViewModel>() .ForMember(dest => dest.Roles, opt => opt.MapFrom(src => src.ProcessRoles.ToDictionary(x => x.Role.Id, x => x.Role.Title))); cfg.DisableStrictMapping(); // 关闭严格映射模式 });
解决方案3:自定义值解析器(适合复杂场景)
如果你的投影逻辑比较复杂,或者需要在多个映射中复用,可以写一个专门的解析器:
public class ProcessRolesToDictionaryResolver : IValueResolver<ProcessActorEntity, ProcessActorViewModel, Dictionary<int, string>> { public Dictionary<int, string> Resolve(ProcessActorEntity source, ProcessActorViewModel destination, Dictionary<int, string> destMember, ResolutionContext context) { return source.ProcessRoles.ToDictionary(x => x.Role.Id, x => x.Role.Title); } } // 然后在映射配置中使用: CreateMap<ProcessActorEntity, ProcessActorViewModel>() .ForMember(dest => dest.Roles, opt => opt.MapFrom<ProcessRolesToDictionaryResolver>());
验证方法
修改后可以用测试代码验证映射是否正常:
var mapper = configuration.CreateMapper(); var testEntity = new ProcessActorEntity { ProcessRoles = new List<ProcessRole> { /* 这里填测试数据 */ } }; var viewModel = mapper.Map<ProcessActorViewModel>(testEntity); // 检查viewModel.Roles是否包含预期的键值对
内容的提问来源于stack exchange,提问作者mRizvandi
相关产品推荐
相关产品推荐

