EF Core 7.0中Owned Properties保存时值丢失的问题排查
EF Core中Owned实体更新时的值丢失问题
问题原因
CurrentValues.SetValues的局限性:EF Core的CurrentValues.SetValues方法仅同步实体的标量属性,Owned类型属于导航属性(复杂类型),不在该方法的处理范围内,所以执行attachedEntry.CurrentValues.SetValues(entity)时,SMS的属性不会被复制到当前追踪的实体中。全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
相关产品推荐
相关产品推荐

