我正在尝试使用 this answer 中的方法复制 Entity Framework 中的对象。 ,但是当我调用 Add(clone)
时,我收到一个 InvalidOperationException 异常,表示违反了多重性约束。我的代码如下所示
var dbSet = context.Set<MyObject>()
var clone = dbSet.Include(e => e.Property1)
.Include(e => e.Property2)
.Include(e => e.Property3)
.AsNoTracking()
.First(e => e.Id == OriginalPrimaryKey)
dbSet.Add(clone); // Throws InvalidOperationException
context.SaveChanges();
堆栈跟踪看起来像
System.InvalidOperationException was unhandled by user code
HResult=-2146233079 Message=Multiplicity constraint violated. The role 'MyObject_Property1_Target' of the relationship 'DataModels.MyObject_Property1' has multiplicity 1 or 0..1. Source=EntityFramework StackTrace: at System.Data.Entity.Core.Objects.EntityEntry.WillNotRefSteal(EntityReference refToPrincipal, IEntityWrapper wrappedPrincipal) at System.Data.Entity.Core.Objects.EntityEntry.FixupEntityReferenceToPrincipal(EntityReference relatedEnd, EntityKey foreignKey, Boolean setIsLoaded, Boolean replaceExistingRef) at System.Data.Entity.Core.Objects.EntityEntry.FixupReferencesByForeignKeys(Boolean replaceAddedRefs, EntitySetBase restrictTo) at
请注意,Property1
是一个完整的对象,其外键返回到 MyObject
。据我所知,多重性错误来自这样一个事实:根据 EF,现有实体和我的克隆之间的 Property1
对象是“相同的”(它们不是引用相等的,我检查过) .
从上面的答案来看,我认为使用 AsNoTracking
EF 会处理这个问题并生成新版本的 Property1
实体以保存到数据库。难道不是这样吗?如果没有,克隆具有所有引用属性的整个实体的最佳方法是什么?
最佳答案
我通过将所有引用属性的主键设置为 0 解决了这个问题。所以我的代码现在看起来像
var dbSet = context.Set<MyObject>();
var clone = dbSet.Include(e => e.Property1)
.Include(e => e.Property2)
.Include(e => e.Property3)
.AsNoTracking()
.First(e => e.Id == OriginalPrimaryKey);
clone.Property1.Id = 0;
clone.Property2.Id = 0;
clone.Property3.Id = 0;
dbSet.Add(clone);
context.SaveChanges();
我不确定这是否是正确的方法——感觉肯定不对——但我找不到其他有效的方法。
关于c# - 尝试克隆 Entity Framework 对象时违反了多重性约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36796079/