2015年11月25日

EntityFramework(20):楽観的同時実行制御 (Timestamp列なし)

  
前回は、Timestamp型/rowversion型のカラムがテーブルに用意されている場合の楽観的同時実行制御について書きましたが、今回は、Timestamp型/rowversion型のカラムが無い場合の楽観的同時実行制御について。

Database Firstで開発している時って、種々の理由でRowVersion列をテーブルに追加 できないことも結構あります。
でも大丈夫、ちょっと面倒くさいけど、そんなときにも対応可能です。
まず、以下のようなpartialクラスを定義します。 classが入れ子になっている点に注意。Metadataクラスに中に、Categoryテーブルの主キー以外の プロパティを定義し、ConcurrencyCheck属性を付加。

 [MetadataType(typeof(Category.Metadata))]
 public partial class Category {
     class Metadata {
         [ConcurrencyCheck]
         public string CategoryName { get; set; }

         [ConcurrencyCheck]
         public string Description { get; set; }

         [ConcurrencyCheck]
         public byte[] Picture { get; set; }
     }
 }

更新のコードは、前回示したものと同じです。

 using (var db = new NorthwindContext()) {
     try {
         db.SetLogging();
         Category cat = db.Categories.First(x => x.CategoryName == "Produce");
         cat.CategoryName = "UpdatedCategory";
         db.SaveChanges();
     } catch (DbUpdateConcurrencyException ex) {
         Console.WriteLine(ex.ToString());
     }
 }

上の更新のコードを実行すると、次のようなSQL文が発行されます。
読み込んだ時の値と、Updateしようとしている時のDBの値が同じかどうかを判断してくれるSQL文になってます。

UPDATE [dbo].[Categories]
SET [CategoryName] = @0
WHERE (((([CategoryID] = @1) AND ([CategoryName] = @2)) 
  AND [Description] IS NULL) AND [Picture] IS NULL)


 

この記事へのトラックバックURL

http://trackback.blogsys.jp/livedoor/gushwell/52440877