redwarrior’s diary

C#, ASP.NET, WEB, G*などの雑多な情報

Entity Framework で楽観的同時実行制御

基本的な内容は以下の書籍に書かれているので、今回はもう少し踏み込んだ話です。 www.shuwasystem.co.jp

上記書籍の5-4-4(236ページ)では、バージョン管理用のプロパティ名と付与する属性名の両方をTimestampとしていますが、どちらを指しているのかわかりにくいので以下ではプロパティ名を「RowVersion」としています。

書籍の通りに、コントローラーの引数にRowVersionプロパティを指定して、Models配下のクラス(データモデル)にBindすると楽観的同時実行制御が行われます。

しかし、データモデルとは別に画面表示用クラス(View Model)を用意していて、オブジェクトの詰め替え作業を行っている場合は、中身を理解して行わないと正しく動作しないため、調べた内容を記述します。

newしたオブジェクトは、Updateで自動判定

プログラム上でnewした(Entity Frameworkによって管理されていない)オブジェクトの場合は、rowversion型のプロパティに値を設定しておけば、Update時に自動的に判定して処理してくれます。

Entity Frameworkから取得したオブジェクトは工夫が必要

Entity FrameworkからFind等で取得したオブジェクトの場合は、以下のようにEntryメソッドの返り値のオブジェクトに対して値を設定する必要があります。

var departmentToUpdate = context.Departments.Find(id); //Entity Frameworkで管理されたオブジェクト
context.Entry(departmentToUpdate).OriginalValues["RowVersion"] = rowVersion; //rowVersionはbyte[]型のパラメータ

当然ですが、どちらの場合でもSaveChangesメソッドが呼ばれた時に更新処理が行われます。

以上です。

参考URL: Handling Concurrency with the Entity Framework 6 in an ASP.NET MVC 5 Application (10 of 12) | Microsoft Docs