实体框架:在单个请求中删除和添加具有相同密钥的实体

时间:2016-07-29 16:58:23

标签: c# entity-framework orm code-first

我需要在一个请求中删除并添加具有相同主键值的实体,有人可以向我建议解决方案吗?

以下是我提供错误的示例代码:违反PRIMARY KEY约束' PK_Table'。无法在对象' dbo.Table'

中插入重复的密钥
context.Set<Entity>().Attach(existingEntityObj);
Entry(existingEntityObj).State = EntityState.Deleted;

context.Set<Entity>().Add(newEntityObj);
context.Entry<Entity>(newEntityObj).State = EntityState.Added;

context.SaveChanges();

假设两个对象(existingEntityObj和newEntityObj)在主键属性中具有相同的值。

提前感谢!!

3 个答案:

答案 0 :(得分:6)

您需要执行两次SaveChanges()调用才能使其正常工作。这里的问题是,虽然看起来你首先删除记录然后添加一个新记录,但框架实际上是先插入插入。

原因是因为实体框架并没有让您精确控制操作发生的订单。所以最好的办法是将两者包装在单独的TransactionScope中,让您控制正在发生的个别交易。

您可以在此处阅读更多内容:https://blogs.msdn.microsoft.com/alexj/2009/01/11/savechangesfalse/

答案 1 :(得分:2)

单个更新语句可以为您工作,因此如果您想保持相同的主键值,解决方案是使用新实体值更新旧实体。由于主键标识实体,因此删除旧实体并添加新实体将与更新具有相同的效果。

如果你觉得我错了,请给我一个完美的例子来纠正我。

答案 2 :(得分:0)

您还可以尝试使用显式的DbContextTransaction,如下所示:

using (DbContextTransaction transaction = context.Database.BeginTransaction())
{
  context.DoSomething();
  context.SaveChanges();

  context.DoSomethingElse();
  context.SaveChanges();

  transaction.Commit();

}

别忘了也捕获异常,然后执行transaction.Rollback();