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

EF Core 7.0中Owned Properties保存时值丢失的问题排查

EF Core中Owned实体更新时的值丢失问题

问题原因

  1. CurrentValues.SetValues的局限性:EF Core的CurrentValues.SetValues方法仅同步实体的标量属性,Owned类型属于导航属性(复杂类型),不在该方法的处理范围内,所以执行attachedEntry.CurrentValues.SetValues(entity)时,SMS的属性不会被复制到当前追踪的实体中。

  2. 全null场景失效的原因:当entity.SMS的所有字段均为null,或者entity.SMS本身为null时,attachedEntry.Reference(x => x.SMS).TargetEntry可能返回null(比如原实体的SMS从未被初始化,或者EF未追踪到该从属实体),此时调用SetValues不会产生任何效果。

解决方案

针对SMS实体的不同状态,分场景处理同步逻辑,覆盖所有null值场景:

Configuration current = DbContext.Set<Configuration>().Find(entity.Key());
EntityEntry<Configuration> attachedEntry = DbContext.Entry(current);

// 同步主实体的标量属性
attachedEntry.CurrentValues.SetValues(entity);

// 处理Owned实体SMS的同步
if (entity.SMS == null)
{
    // 若新的SMS为null,直接置空当前实体的SMS
    current.SMS = null;
}
else
{
    var smsReference = attachedEntry.Reference(x => x.SMS);
    if (smsReference.TargetEntry == null)
    {
        // 若当前未追踪SMS实体,创建新实例并关联
        current.SMS = new SMSConfiguration();
    }
    // 同步SMS的所有属性(包括全null的情况)
    smsReference.TargetEntry.CurrentValues.SetValues(entity.SMS);
}

attachedEntry.State = EntityState.Modified;
DbContext.SaveChanges();

补充说明

Owned类型在EF Core中是主实体的不可分割部分,数据库中通常会将其字段嵌入主实体表(默认配置),所以更新时必须确保从属实体被正确追踪和赋值。上述代码通过判断TargetEntry的存在性,覆盖了SMS为null、部分字段为null、全字段为null的所有场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 18:02:50