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

AutoMapper技术问题:如何处理目标对象中源对象无对应字段

问题:AutoMapper更新目标对象时保留未映射字段原有值

当使用源对象更新目标对象时,源对象中不存在的字段会被设置为null,导致目标对象原有值丢失。希望实现仅覆盖源对象存在的字段,保留目标对象其他字段的原有值。


示例代码

源对象类

public class SourceObj{
  public int Id {get; set; }
  public string Name {get; set; }
  public string Value1{get; set; }
}

目标对象类

public class TargetObj{
  public int Id {get; set; }
  public string Name {get; set; }
  public string Value1{get; set; }
  public string Value2{get; set; }
  public string Value3{get; set; }
}

映射场景

目标对象初始状态:

{
  Id: 1,
  Name: 'name1',
  Value1: 'value1',
  Value2: 'value2',
  Value3: 'value3',
}

源对象内容:

{
  Id: 1,
  Name: 'name1',
  Value1: 'value1Updated'
}

默认映射配置:

CreateMap<SourceObj, TargetObj>();

当前结果与期望结果

当前更新后目标对象(不符合预期):

{
  Id: 1,
  Name: 'name1',
  Value1: 'value1Updated',
  Value2: null,
  Value3: null,
}

期望结果:

{
  Id: 1,
  Name: 'name1',
  Value1: 'value1Updated',
  Value2: 'value2',
  Value3: 'value3',
}

已尝试但无效的配置

CreateMap<SourceObj, TargetObj>(MemberList.Source);
CreateMap<SourceObj, TargetObj>(MemberList.None);

解决方案

要保留目标对象未映射字段的原有值,需使用AutoMapper的对象更新重载方法,而非创建新对象的映射方法:

  1. 保持基础映射配置不变:
CreateMap<SourceObj, TargetObj>();
  1. 使用传入目标对象实例的Map重载方法执行更新:
// 初始化已有目标对象
var target = new TargetObj 
{
  Id = 1,
  Name = "name1",
  Value1 = "value1",
  Value2 = "value2",
  Value3 = "value3"
};

// 准备源对象
var source = new SourceObj 
{
  Id = 1,
  Name = "name1",
  Value1 = "value1Updated"
};

// 执行更新:仅覆盖源对象存在的字段
Mapper.Map(source, target);

执行后,target的Value2和Value3会保留原有值,不会被设为null。

原理说明

  • Mapper.Map(source, destination)是专门用于更新已有对象的方法,只会覆盖源对象中存在的字段,未匹配的字段保留目标对象原有值。
  • 若使用Mapper.Map<SourceObj, TargetObj>(source),则会创建全新的目标对象,未映射字段会被设为类型默认值(引用类型为null)。
  • MemberList参数仅用于验证映射的完整性,和字段是否被覆盖无关,因此之前尝试的配置无法解决问题。

内容的提问来源于stack exchange,提问作者Todd Greenwald

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 14:20:23