0

我正在使用 EF 4.4,我想更新许多实体,但其他一些用户可以修改第一个用户修改的许多实体。所以我得到一个并发异常。其他情况是第一个用户尝试添加许多新寄存器,而其他用户同时添加了其中一些。所以我有一个存在一些寄存器的异常(唯一约束)。

我想确保第一个用户完成他的操作,只添加尚不存在的寄存器(添加他的所有实体,除了第二个用户添加的实体)。

为此,我需要更新 dbContext 中的实体,以便我看到至少有两个选项。

首先,在捕获更新异常时的捕获中,我可以这样做:

ex.Entries.Single().Reload();

第二个选项是:

myContext.Entry<MyTable>(instance).Reload();

我猜第二个选项只刷新我用作参数的实体,但如果问题是我需要刷新许多实体,我该怎么做?

第一个选项到底是什么Single().Reload

4

2 回答 2

1

当你这样做

ex.Entries.Single().Reload();

您确定违规实体已刷新。所做的是从无法保存到数据库中的唯一 ( Single) 实体中获取(在并发异常的情况下,这始终是一个)。DbUpdateConcurrencyException.Entries

当你这样做

myContext.Entry(instance).Reload();

除非您知道在调用之前只有一个实体发生了更改,否则您不确定是否刷新了正确的实体SaveChanges。如果您保存具有子实体的实体,其中任何一个都可能导致并发问题。

于 2013-05-04T19:37:05.633 回答
0

在 EF 6.x (6.1.3) 中,下面的代码将让您找到所有更改;您在问题中提出的方式!

try
{
  var listOfRefreshedObj = db.ChangeTracker.Entries().Select(x => x.Entity).ToList();
  var objContext = ((IObjectContextAdapter)your_db_context).ObjectContext;
  objContext.Refresh(System.Data.Entity.Core.Objects.RefreshMode.ClientWins, listOfRefreshedObj);

  await db.Entry(<yourentity>).ReloadAsync();
  return Content(HttpStatusCode.<code>, "<outputmessage>"); ;
}
catch (Exception e)
{
  return Content(HttpStatusCode.<code>, "<exception>");
}

说明:Entries在列表中 查询ChangeTracker并将它们存储在列表中

var listOfRefreshedObj = db.ChangeTracker.Entries().Select(x => x.Entity).ToList();

接下来是刷新上下文。在某些情况下(行被删除等),这将引发您可以捕获的异常。RefreshMode.ClientWins告诉 EF 在下次更新时接受所有已修改的客户端单元。在某些情况下,您可能希望提示用户进行更改并让他们决定。刷新模式枚举。一个例子在这里ObjectContext.Refresh 方法示例

objContext.Refresh(System.Data.Entity.Core.Objects.RefreshMode.ClientWins, listOfRefreshedObj);

无论如何,您可能正在做这整件事DbUpdateConcurrencyException

于 2017-03-14T06:38:50.680 回答