You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
    }));

方法二:拆分映射+集合过滤(适合复杂扩展场景)

如果后续需要添加更多联系人类型,可以先为单个联系人创建独立映射,再通过逻辑过滤空值:

  1. 配置单个联系人的映射规则:
// 手机号联系人映射
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");
  1. 主映射中生成并过滤联系人列表:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 19:15:40