【问题标题】:Cloning entity fails with primary-key violation on SaveChanges()克隆实体因 SaveChanges() 上的主键违规而失败
【发布时间】:2016-04-26 03:51:26
【问题描述】:

我正在尝试复制here 中描述的实体。在我的实体包装器基类中,我有以下代码来复制/克隆实体。

public TBaseEntityModel Clone(TPrimaryKey newPrimaryKey)
{
    var newEntity = Activator.CreateInstance<TEntity>();
    var clone = DbContext.Entry(newEntity);
    clone.State = EntityState.Added;
    DbContext.Entry(newEntity).CurrentValues.SetValues(TheEntity);
    clone.State = EntityState.Detached;
    var cloneEntityModel= (TBaseEntityModel)Activator.CreateInstance(typeof(TBaseEntityModel), DbContext, newEntity);
    cloneEntityModel.PrimaryKeyValue = newPrimaryKey;
    return cloneEntityModel;
}

在我对具体实体调用Clone-方法后,它的新主键也设置为newPrimaryKey 的给定值。

当我在底层上下文上调用SaveChanges() 时,就会出现问题。

然后抛出:

Violation of PRIMARY KEY constraint '...'. Cannot insert duplicate key in object 'dbo....'. The duplicate key value is (553a7aa9-0ac2-40a0-820f-43a3b4af745f).

但是当我查看我的clone 时,PK 设置为另一个值。 所以我猜是ObjectContext 里面的东西,甚至更深的东西。

但我不知道如何摆脱错误。

【问题讨论】:

  • TBaseEntityModel的构造函数发生了什么?
  • 它只设置DbContextTheEntity这两个属性都在Clone方法中使用。它还设置了一个布尔标志,它将在SaveChanges() 之前将实体的状态设置为Added。也许有问题?
  • 如果没有所有这些不可见的活动部件,很难分辨。无论如何,我不会为实体提供对上下文的引用。克隆方法应该简单地做到这一点:创建一个克隆。它不应该参与克隆的状态。

标签: c# entity-framework entity-framework-6 primary-key


【解决方案1】:

我怀疑数据库正在尝试生成主键,但您还试图在保存之前明确指定它。如果要为标识列指定值,则需要跳过一些环节 (How can I force entity framework to insert identity columns?)。否则,只需不要设置该值,它会在您执行插入时为您生成。

【讨论】:

  • 绝对不是生成pk的数据库。使用 DbContext.Set&lt;MyEntity&gt;().Add(new MyEntity{Primary = Guid.NewGuid()}); 可以正常工作。因此,明确指定它不是问题。我仍然认为 EF 保留对“旧”键的引用,该键在插入克隆实体时崩溃
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-14
  • 1970-01-01
  • 2017-08-20
  • 1970-01-01
  • 2015-05-08
  • 1970-01-01
  • 2019-11-07
相关资源
最近更新 更多