AutoMapper条件映射:非空时向联系人列表添加元素的问题
AutoMapper 条件集合映射解决方案
你的代码问题在于错误地在ForMember中直接实例化列表并嵌套MapFrom,这不符合AutoMapper的配置语法,同时会导致无法过滤空元素。以下是两种可行的解决思路:
方法一:使用ResolveUsing构建过滤后的联系人列表
直接在属性映射中编写逻辑,根据源对象的非空条件添加联系人,确保列表中没有空元素:
CreateMap<UserModel, UserDefinition>() .ForMember(d => d.Id, o => o.Ignore()) .ForMember(d => d.UserName, o => o.MapFrom(s => s.Username)) .ForMember(d => d.Contacts, o => o.ResolveUsing(src => { var contacts = new List<UserContactDefinition>(); // 手机号非空时添加 if (!string.IsNullOrWhiteSpace(src.PhoneNumber)) { contacts.Add(new UserContactDefinition { Type = ContactType.Phone, IsPrimary = true, Label = src.PhoneType, Value = src.PhoneNumber }); } // 邮箱非空时添加 if (!string.IsNullOrWhiteSpace(src.ContactEmail)) { contacts.Add(new UserContactDefinition { Type = ContactType.Email, IsPrimary = true, Label = src.EmailType, Value = src.Email }); } return contacts; }));
方法二:拆分映射+集合过滤(适合复杂扩展场景)
如果后续需要添加更多联系人类型,可以先为单个联系人创建独立映射,再通过逻辑过滤空值:
- 配置单个联系人的映射规则:
// 手机号联系人映射 CreateMap<UserModel, UserContactDefinition>() .ForMember(d => d.Type, o => o.MapFrom(_ => ContactType.Phone)) .ForMember(d => d.IsPrimary, o => o.MapFrom(_ => true)) .ForMember(d => d.Label, o => o.MapFrom(s => s.PhoneType)) .ForMember(d => d.Value, o => o.MapFrom(s => s.PhoneNumber)); // 邮箱联系人映射(命名区分) CreateMap<UserModel, UserContactDefinition>() .ForMember(d => d.Type, o => o.MapFrom(_ => ContactType.Email)) .ForMember(d => d.IsPrimary, o => o.MapFrom(_ => true)) .ForMember(d => d.Label, o => o.MapFrom(s => s.EmailType)) .ForMember(d => d.Value, o => o.MapFrom(s => s.Email)) .Named("EmailContact");
- 主映射中生成并过滤联系人列表:
CreateMap<UserModel, UserDefinition>() .ForMember(d => d.Id, o => o.Ignore()) .ForMember(d => d.UserName, o => o.MapFrom(s => s.Username)) .ForMember(d => d.Contacts, o => o.ResolveUsing((src, dest, _, context) => { var contacts = new List<UserContactDefinition>(); if (!string.IsNullOrWhiteSpace(src.PhoneNumber)) { contacts.Add(context.Mapper.Map<UserContactDefinition>(src)); } if (!string.IsNullOrWhiteSpace(src.ContactEmail)) { contacts.Add(context.Mapper.Map<UserContactDefinition>(src, opt => opt.MapFromNamedProfile("EmailContact"))); } return contacts; }));
关键说明
- 原代码核心错误:
ForMember的配置参数应为映射规则(如MapFrom/ResolveUsing),而非直接实例化集合;MapFrom仅用于单个值的映射,无法处理多元素集合的条件过滤。 - 两种方法均能确保仅添加非空的联系人项,避免列表中出现
null元素,且符合AutoMapper的配置规范。
内容的提问来源于stack exchange,提问作者Sachin
相关产品推荐
相关产品推荐

