尝试克隆 Entity Framework 对象时违反了多重约束

Multiplicity constraint violated when trying to clone Entity Framework object

我正在尝试使用 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 对象是 "the same"(我检查过,它们的引用不相等)。

从上面的答案来看,我认为在使用 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();

我不确定这是否是正确的方法——它肯定感觉不对——但我还没有找到任何其他有效的方法。