OK、私はこれらを読みました:
EntityFramework 変更を保存する前にエンティティを表示
追加されたオブジェクトは ObjectContext のどこに保存されますか?
問題の明確な解決策はないと思いますが (2 回目の投稿は 2009 年のものですが)、Entity Framework の重要な問題だと思うので、それでも質問します。
次のようなコードがあるとします。
// Get somehow an UnitOfWork instance, e.g. using factory
var categoryRepository = new CategoryRepository(unitOfWork);
var newCategory = new Category("Some Category");
categoryRepository.Add(newCategory);
var allCategories = categoryRepository.GetAll();
Debug.Assert(allCategories.Contains(newCategory));
unitOfWork.Commit();
NHibernate を使用する場合、UnitOfWork 実装は ISession インスタンスをカプセル化します。そして、指定されたコードは期待どおりに動作します。変更がコミットされる前に、新しく追加されたカテゴリをリポジトリ (つまり、基礎となる ISession) から取得できます。
Entity Framework の動作が異なることに驚きました。UnitOfWork 実装が EF の ObjectContext をカプセル化する場合、アサーションは失敗します。( unitOfWork.Commit() メソッドで) ObjectContext.SaveChages() を呼び出す前は、新しく追加されたカテゴリには (同じ ObjectContext を介して) 到達できません。この動作を構成する ObjectContext のプロパティを見つけようとしましたが、成功しませんでした。
だから私の質問は: ObjectContext.SaveChages() を呼び出す必要なく追加したばかりの ObjectContext からエンティティを取得することは可能ですか (ビジネス トランザクションが終了するまでコミットしたくないため)? 答えが「いいえ」の場合、これは特にアイデンティティ マップ デザイン パターンおよび UnitOfWork パターン全般に対する違反ではありませんか? また、EF を使用する場合、このシナリオにどのように対処しますか?
前もって感謝します。
皆さん、遅れてすみません。
あなたは私の言いたいことを理解していないようです。問題は、「追加したばかりのこのインスタンスを取得する方法」ではありません。結局のところ、私はそれを参照しています。問題は、「新しく追加された (まだコミットされていない - 実際にはコミットされない可能性がある) エンティティは、指定された DbSet に対するクエリでどのように考慮されるのですか?」
新しいカテゴリを追加して、そのようなものを書いた場合 (ここでは意図的にリポジトリを使用していませんが、わかりやすくするために DbContext (または EF 4.0 を使用している場合は ObjectContext) を行しています):
var selectedCategories = context.Categories.Where(c => c.ParentCategory.Name == "Some Category Name");
条件を満たした場合、新しいカテゴリが結果セットに返されるようにします。おそらく、このクエリは、単一のトランザクション (作業単位) 内で同じコンテキスト (リポジトリ) を共有する別のメソッド (または別のクラス) で実行されます。Categories.Local に対して同じクエリを実行し、新しく追加されたエンティティのみに結果をフィルター処理して (Local には現在追跡されているセットのすべてのエンティティが含まれているため)、それをデータベースから返された結果と組み合わせることができることを知っています。すごく醜いと思いませんか?そして、今何かが欠けていないかどうかさえわかりません。これはすべて ORM の作業です。それはすべてトランザクションの動作 (作業単位) に関するものであり、ORM がそれを処理する必要があります (NHibernate のように)。
今、それはあなたにとって意味がありますか?