【问题标题】:DbContext, handling concurrency exceptionDbContext,处理并发异常
【发布时间】:2012-12-01 06:24:09
【问题描述】:

使用EF DbContext。我的实体对象有 rowversion 列(SQL Compact edition ver 4),用于并发检查(ConcurrencyMode = Fixed, StoreGeneratedPattern=Computed)。

为了强制并发异常,我从 UI 中读取了 2 种不同形式的同一个表记录,分别编辑它们,并一个接一个地保存。以下代码执行实际的保存操作。

单击第二个表单上的保存按钮时,按预期发生并发错误。然而, 从数据库复制原始值后,该异常在第二次尝试时仍然存在。只有第三次尝试成功,没有任何错误。有人可以解释一下可能导致此问题的原因吗?

try
{
  _ctx.SaveChanges(); //first attempt
}
catch (Exception ex)
{
  if (ex is DbUpdateConcurrencyException)
  {
    var exc = ex as DbUpdateConcurrencyException;
    foreach (var entry in exc.Entries)
      entry.OriginalValues.SetValues(entry.GetDatabaseValues());
    try
    {
      _ctx.SaveChanges(); //second attempt
    }
    catch (Exception ex2)
    {
      if (ex2 is DbUpdateConcurrencyException)
      {
        var exc2 = ex2 as DbUpdateConcurrencyException;
        foreach (var entry in exc2.Entries)
          entry.OriginalValues.SetValues(entry.GetDatabaseValues());
        try
        {
          _ctx.SaveChanges(); //third attempt
        }
        catch (Exception ex3)
        {
          System.Windows.MessageBox.Show(ex3.Message);
        }
      }
    }
  }
}

编辑:我发现它发生在我通过 UI 进行两次更新时。如果在上面的代码中,在第一次尝试之前,我会做以下事情:

var _ctx2 = new MyDbContext();
var myEntity = _ctx2.MyEntities.Where(ent => ent.Id == 2).Single();
myEntity.Name = "My new name";
_ctx2.SaveChanges();
_ctx2.Dispose();

然后代码按预期工作,因为 myEntity 的另一个实例是通过 UI 更新的;即第二次尝试将保存 myEntity。 而且,问题出在以下行:

foreach (var entry in exc.Entries)
  entry.OriginalValues.SetValues(entry.GetDatabaseValues());

因为,当通过 UI 更新时,exc.Entries 返回的不是发生并发错误的实体,而是它的导航属性实体。

在这种情况下,MyEntity 是一个树状自引用实体,它有两个导航属性:ParentEntity 和 Children。

因此,在第一次保存尝试后,我在 exc.Entries 中拥有的是 ParentEntity(处于未更改状态),并且只有在第二次保存尝试后,exc.Entries 返回引发并发错误的实际实体。

【问题讨论】:

  • Side Note: 您可以使用catch(DbUpdateConcurrencyException ex) 而不是使用if 检查异常类型。

标签: entity-framework dbcontext optimistic-concurrency


【解决方案1】:

好的,这似乎是一个 EF 错误。请参阅以下内容:

http://support.microsoft.com/kb/2390624#appliesto
http://social.msdn.microsoft.com/Forums/en/adodotnetentityframework/thread/ce60bf40-cd05-42f6-ab8f-26b048ec83d7

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-21
    • 1970-01-01
    • 1970-01-01
    • 2015-08-06
    • 1970-01-01
    • 1970-01-01
    • 2013-02-13
    • 1970-01-01
    相关资源
    最近更新 更多