1

EF DbContext を使用します。私のエンティティ オブジェクトには、同時実行チェック (ConcurrencyMode = Fixed、StoreGeneratedPattern = Computed) に使用される rowversion 列 (SQL Compact エディション バージョン 4) があります。

同時実行例外を強制するために、UI から同じテーブル レコードを 2 つの異なるフォームで読み取り、それぞれを編集して、次々に保存しました。次のコードは、実際の保存操作を行います。

2 番目のフォームの保存ボタンをクリックすると、予期したとおりに同時実行エラーが発生します。ただし、データベースから元の値をコピーした後、2 回目の試行では例外が引き続き発生します。3 回目の試行のみがエラーなしで成功します。誰かがこの問題の原因を説明できますか?

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 を介して更新された場合、コードは期待どおりに機能します。つまり、2 回目の試行で myEntity が保存されます。そして、問題は次の行にあります。

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

UI を介して更新すると、 exc.Entries は同時実行エラーが発生したエンティティではなく、そのナビゲーション プロパティ エンティティを返すためです。

この場合、MyEntity はツリー状の自己参照エンティティであり、ParentEntity と Children の 2 つのナビゲーション プロパティがあります。

したがって、最初の保存試行の後、exc.Entries にあるのは (変更されていない状態の) ParentEntity であり、2 回目の保存試行の後でのみ、exc.Entries は同時実行エラーがスローされた実際のエンティティを返します。

4

1 に答える 1

1

わかりました、EF のバグのようです。以下を参照してください。

http://support.microsoft.com/kb/2390624#appliesto
http://social.msdn.microsoft.com/Forums/en/adodotnetentityframework/thread/ce60bf40-cd05-42f6-ab8f-26b048ec83d7
于 2012-12-15T09:18:48.270 に答える