我正在尝试使用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未被用户代码
处理 HResult = -2146233079 Message =违反了Multiplicity约束。该 角色&#39; MyObject_Property1_Target&#39;关系 &#39; DataModels.MyObject_Property1&#39;具有 多重性1或0..1。 Source = EntityFramework StackTrace: 在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) 在
请注意,Property1
是一个完整的对象,其外键返回MyObject
。据我所知,多重性错误来自于现有实体和我的克隆之间的Property1
对象是&#34;相同的&#34;根据EF(他们不是参考,我检查过)。
从上面的回答看,我想在使用AsNoTracking
EF时会处理这个问题并生成新版本的Property1
实体以保存到数据库中。这不是这种情况吗?如果没有,用所有引用的属性克隆整个实体的最佳方法是什么?
答案 0 :(得分:4)
我通过将所有引用属性的主键设置为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();
我不确定这是否是正确的做法 - 当然感觉不对 - 但我找不到其他有效的方法。