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

AutoMapper映射列表时忽略目标多余属性避免被置空

问题解决步骤

1. 修正代码冗余与语法错误

首先移除重复定义的Person、PersonDTO、Info、InfoDTO类,避免编译冲突。同时修正映射配置中的语法错误:

public class PersonProfile : Profile
{
    public PersonProfile()
    {
        CreateMap<PersonDTO, Person>()
            .ForMember(d => d.FirstName, opt => opt.MapFrom(src => src.FirstName))
            .ForMember(d => d.LastName, opt => opt.MapFrom(src => src.LastName))
            .ForMember(d => d.Information, opt => opt.ResolveUsing<PersonCollectionResolver>());

        CreateMap<InfoDTO, Info>()
            .ForMember(d => d.info1, opt => opt.MapFrom(src => src.info1))
            .ForMember(d => d.info2, opt => opt.MapFrom(src => src.info2))
            .ForMember(d => d.info3, opt => opt.Ignore()); // 修正opt.opt为opt
    }
}

2. 实现集合更新自定义解析器

AutoMapper默认会替换整个集合并创建新元素,导致原有info3值丢失。我们需要自定义解析器来逐个更新已有元素:

public class PersonCollectionResolver : IValueResolver<PersonDTO, Person, List<Info>>
{
    private readonly IMapper _mapper;

    public PersonCollectionResolver(IMapper mapper)
    {
        _mapper = mapper;
    }

    public List<Info> Resolve(PersonDTO source, Person destination, List<Info> destMember, ResolutionContext context)
    {
        // 源集合为空时,保留目标原有集合
        if (source.Information == null)
            return destMember;
        
        // 目标集合为空时,直接映射源集合生成新元素
        if (destMember == null)
            return _mapper.Map<List<Info>>(source.Information);
        
        // 逐个更新对应位置的元素(假设列表顺序匹配)
        int minCount = Math.Min(source.Information.Count, destMember.Count);
        for (int i = 0; i < minCount; i++)
        {
            // 使用Map更新已有Info对象,info3会被忽略保留原值
            _mapper.Map(source.Information[i], destMember[i]);
        }
        
        // 源集合有新增元素时,添加到目标集合
        for (int i = minCount; i < source.Information.Count; i++)
        {
            destMember.Add(_mapper.Map<Info>(source.Information[i]));
        }
        
        // 如需删除目标集合中多余元素,可在此添加逻辑,此处默认保留
        return destMember;
    }
}

3. 注册解析器并验证

确保自定义解析器已注入DI容器(如果使用依赖注入),之后调用_mapper.Map(personDTOUpdated, person)时,Person.Information中的原有info3值将被保留,仅更新info1和info2。

关键说明

  • 忽略info3的配置确保单个元素映射时不会覆盖原有值;
  • 自定义解析器避免了集合被整体替换,实现了元素级的更新逻辑;
  • 如果Info类有唯一标识(如Id),可以修改解析器逻辑,根据标识匹配元素而非依赖顺序,提升可靠性。

内容的提问来源于stack exchange,提问作者Jim Buschman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 12:00:01