taediumの日記

2010-08-08

[][] Entity Frameworkの不便なところ

バージョン番号の自動インクリメント

楽観的排他制御のためにWHERE句に特定のカラムを条件として入れる機能はありますが、「バージョン番号」という考え方がないんですね。したがって、バージョン番号を自動でインクリメントする機能もありません。

これは不便なのでSomaで対応しようと思います。

使う側は、バージョン番号を意識することなく普通に更新処理を行います(CSDLにConcurrencyMode="Fixed"を設定しておく必要はあります)。

var employeeRepository = new EmployeeRepository();
var employee = employeeRepository.SelectById(1);

Console.WriteLine(employee.VersionNo); // 0

employee.EmployeeName = "hoge";
employeeRepository.Update(employee);

Console.WriteLine(employee.VersionNo); // 1

発行されるSQLはこうなります。

update [dbo].[Employee]
set [EmployeeName] = 'hoge', [VersionNo] = 1, [DepartmentId] = 1
where (([EmployeeId] = 1) and ([VersionNo] = 0))

set句に指定されるVersionNoの値が0から1にインクリメントされています。

オブジェクトコンテキストからのデタッチ

Entity Frameworkって、オブジェクトコンテキストを閉じてもエンティティを自動でデタッチしてくれないんですよね。たとえば標準のAPIで更新したときのエンティティの状態を見てみます。

Employee emp = null;
using (var context = new SampleEntities())
{
    emp = context.Employee.Single(e => e.EmployeeId == 1);
    emp.EmployeeName = "hoge";
    context.SaveChanges();
}
Console.WriteLine(emp.EntityState); // Unchanged

この例だと状態はUnchangedになっていますが、直感的にはcontextが閉じられたら紐つくエンティティの状態は全部Detachedになるのがわかりやすいと思うんです。Detachedにならないと、関連オブジェクトを辿ったときに遅延ローディングしようとしてエラーになったりするんですよね。

Somaでは、オブジェクトコンテキストを閉じる直前ですべてのエンティティを自動でデタッチしようと思います。つまり、SomaのRepositoryから返されるエンティティはすべてDetachedな状態になる予定です。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/taedium/20100808/p2