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

Automapper v6.2.2更新仅映射字段:未映射字段被置空求助

解决Automapper更新时未映射字段被置为null的问题

我刚接触Automapper时也踩过一模一样的坑,你遇到的核心问题其实是创建了全新的目标对象,而非将源数据映射到已从数据库加载的现有实体上,这才导致未映射字段被覆盖成null。

问题根源分析

当你执行Mapper.Map<TDomain>(entity)时,Automapper会生成一个全新的PT_Registration实例——那些没配置映射的属性(比如EMail_VC和Comments_VC)会被初始化为默认值null。接着你把这个新对象的状态设为EntityState.Modified,EF会认为所有属性都需要更新,自然就把数据库里的原有值覆盖成null了。

之前你尝试的ForAllOtherMembers(opt => opt.Ignore())、MemberList配置等之所以没用,是因为这些配置只控制映射过程中是否覆盖属性,但你是在创建新对象,未映射属性本来就是null,根本没有“原有值”可以保留。

可行解决方案

正确的做法是:先从数据库加载要更新的现有实体,再将源对象的属性映射到这个现有实体上,而非创建新对象。

修改Repository.cs代码:

// 1. 先从数据库获取要更新的现有实体(替换成你的查询逻辑,比如用ID查找)
var existingRegistration = DatabaseContext.PT_Registration.Find(registrationId);

// 2. 将源对象的属性映射到现有实体,而非创建新对象
Mapper.Map(entity, existingRegistration);

// 3. 无需手动设置EntityState.Modified!
// EF的变更追踪会自动识别哪些属性被修改,只更新变化的字段
// 如果你的上下文关闭了自动追踪,才需要手动标记,但通常不需要这一步
// DatabaseContext.Entry(existingRegistration).State = EntityState.Modified;

确保映射配置正确:

你的InvoiceLineMapping.cs里必须加上ForAllOtherMembers(opt => opt.Ignore()),确保Automapper不会覆盖未配置映射的属性:

public static void Map(IProfileExpression profile)
{
    profile.CreateMap<Registration, PT_Registration>()
        .ForMember(d => d.Name_VC, map => map.MapFrom(s => s.Name))
        .ForMember(d => d.UserName_VC, map => map.MapFrom(s => s.Username))
        .ForMember(d => d.Mobile_VC, map => map.MapFrom(s => s.Mobile))
        .ForAllOtherMembers(opt => opt.Ignore()); // 关键:忽略所有未配置的成员
}

额外说明

  • MemberList.Source/Destination是用来做映射验证的(比如检查是否有未映射的源/目标成员),和属性覆盖问题无关,不用在这个场景里纠结。
  • ReverseMap()只是创建反向映射(从PT_Registration到Registration),和当前更新逻辑无关。
  • 不要尝试“移除目标对象的null值”,这是绕远路,Automapper+EF的正确姿势就是映射到现有实体。

这样修改后,EMail_VC和Comments_VC会保留数据库里的原有值,只有你配置的三个字段会被更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:45:49