エンティティフレームワーク-並行性
データアクセスの開発者は、「複数の人が同じデータを同時に編集しているとどうなるか」というデータの同時実行性に関する質問に答える際に困難に直面します。
私たちの中でより幸運なのは、「問題ありません。最後の1つが勝ちです」というビジネスルールを扱っていることです。
この場合、並行性は問題ではありません。おそらく、それはそれほど単純ではなく、すべてのシナリオを一度に解決する特効薬はありません。
デフォルトでは、Entity Frameworkは「最後の勝ち」のパスを取ります。つまり、データが取得されてから保存されるまでの間に他の誰かがデータを更新した場合でも、最新の更新が適用されます。
それをよりよく理解するために例を見てみましょう。次の例では、Courseテーブルに新しい列VersionNoを追加します。
                デザイナに移動し、デザイナウィンドウを右クリックして、データベースからモデルの更新を選択します…
                コースエンティティに別の列が追加されていることがわかります。
                次の図に示すように、新しく作成された列VersionNoを右クリックし、[プロパティ]を選択して、ConcurrencyModeをFixedに変更します。
                Course.VersionNoのConcurrencyModeがFixedに設定されている場合、コースが更新されるたびに、UpdateコマンドはEntityKeyとVersionNoプロパティを使用してコースを検索します。
簡単なシナリオを見てみましょう。2人のユーザーが同時に同じコースを取得し、ユーザー1がそのコースのタイトルをMathsに変更し、ユーザー2の前に変更を保存します。後でユーザー2が、ユーザー1が変更を保存する前に取得したコースのタイトルを変更すると、ケースユーザー2は同時実行例外を取得します"User2: Optimistic Concurrency exception occured"。
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
namespace DatabaseFirstDemo {
   class Program {
      static void Main(string[] args) {
         Course c1 = null;
         Course c2 = null;
         //User 1 gets Course
         using (var context = new UniContextEntities()) {
            context.Configuration.ProxyCreationEnabled = false;
            c1 = context.Courses.Where(s ⇒ s.CourseID == 1).Single();
         }
         //User 2 also get the same Course
         using (var context = new UniContextEntities()) {
            context.Configuration.ProxyCreationEnabled = false;
            c2 = context.Courses.Where(s ⇒ s.CourseID == 1).Single();
         }
         //User 1 updates Course Title
         c1.Title = "Edited from user1";
         //User 2 updates Course Title
         c2.Title = "Edited from user2";
         //User 1 saves changes first
         using (var context = new UniContextEntities()) {
            try {
               context.Entry(c1).State = EntityState.Modified;
               context.SaveChanges();
            } catch (DbUpdateConcurrencyException ex) {
               Console.WriteLine("User1: Optimistic Concurrency exception occurred");
            }
         }
         //User 2 saves changes after User 1.
         //User 2 will get concurrency exection
         //because CreateOrModifiedDate is different in the database
         using (var context = new UniContextEntities()) {
            try {
               context.Entry(c2).State = EntityState.Modified;
               context.SaveChanges();
            } catch (DbUpdateConcurrencyException ex) {
               Console.WriteLine("User2: Optimistic Concurrency exception occurred");
            }
         }
      }
   }
}