如何在Automapper的列表间映射中忽略指定成员?
解决AutoMapper列表映射时
ForMember忽略规则不生效的问题 嘿,我之前也踩过AutoMapper集合映射的坑,咱们来一步步拆解你的问题:
首先,你提到单个对象映射正常,但列表映射时ForMember的忽略规则没生效,看你的代码,问题大概率出在集合映射的用法上。
问题根源
你现在用的是Map(editModel, destModel)这个重载,这是AutoMapper用来更新已有目标对象/集合的方法,而不是用来创建新的映射集合的。当你用这个重载处理集合时,AutoMapper的逻辑是:
- 先尝试匹配源集合和目标集合里的元素(默认用主键或者对象相等性)
- 对匹配上的元素,应用单个对象的映射规则更新
- 新增/缺失的元素会默认添加/移除(取决于配置)
但你的代码里,destModel是从服务获取的List<SmsContact>,而你要映射到SmsContactViewModel列表,这时候用更新重载就不对了——你应该是要创建一个全新的目标列表,而不是更新已有集合。
解决方案
方案1:创建全新的目标列表(推荐)
直接调用Map的泛型版本,让AutoMapper帮你生成新的目标集合,这样单个对象的映射规则(包括忽略PhoneNumber)会自动应用到每个元素上:
// 获取源列表 var sourceContacts = _smsContactService.GetAll(a => true).ToList(); // 创建映射器(注意:实际项目里最好把Mapper做成全局单例,不要每次都创建) var mapper = mapperConfig.CreateMapper(); // 映射为全新的目标列表 var destViewModels = mapper.Map<List<SmsContactViewModel>>(sourceContacts);
方案2:如果必须更新已有目标集合
如果你确实需要更新一个已有的List<SmsContactViewModel>,那要注意这几点:
- 确保源集合和目标集合的类型对应(源是
List<SmsContact>,目标是List<SmsContactViewModel>) - 确保AutoMapper能正确匹配源和目标元素(如果没有主键,可以在映射配置里指定
EqualityComparison) - 调用更新重载时参数顺序别搞反:
Map(源集合, 已有目标集合)
示例代码:
// 已有目标集合 var existingViewModels = new List<SmsContactViewModel>(); // 源集合 var sourceContacts = _smsContactService.GetAll(a => true).ToList(); var mapper = mapperConfig.CreateMapper(); // 更新已有集合 mapper.Map(sourceContacts, existingViewModels);
额外验证步骤
为了确保你的映射配置没问题,可以在创建MapperConfiguration后加上验证代码,这样如果配置有错误(比如未映射的成员),会直接抛出异常提醒你:
var mapperConfig = new MapperConfiguration(a => { var b = a.CreateMap<SmsContact, SmsContactViewModel>() .IgnoreAllPropertiesWithAnInaccessibleSetter() .IgnoreAllSourcePropertiesWithAnInaccessibleSetter(); b.ForMember(v => v.PhoneNumber, v => v.Ignore()); }); // 验证配置是否正确 mapperConfig.AssertConfigurationIsValid();
内容的提问来源于stack exchange,提问作者a.shakouri
相关产品推荐
相关产品推荐

