13

ここや他のフォーラムでさまざまな質問をした結果、Entity Framework で生成されたエンティティ コンテキスト オブジェクトに関して、自分が何をしているのかわからないという結論に達しました。

背景として、私は LLBLGen Pro を使用した経験が豊富であり、Entity Framework は私にとって約 3 週間前のものです。

「myContext」というコンテキストがあるとしましょう。私のモデルには Employee というテーブル/エンティティがあるため、myContext.Employees が作成されました。これは、このプロパティがコンテキスト内の Employee エンティティのセットを表していることを意味すると思います。ただし、次の方法で新しいエンティティをコンテキストに追加できるため、間違っていると思います。

myContext.Employees.AddObject(new Employee());

この新しい Employee エンティティは、myContext.Employees のどこにも表示されません。私が集めた情報によると、この新しく追加されたエンティティを見つける唯一の方法は、myContext.ObjectStateManager に隠れているエンティティを追跡することです。これは、myContext.Employees セットが実際にはコンテキスト内の Employee エンティティのセットではなく、データベースに存在する Employee エンティティの何らかの表現であるように思えます。

この混乱をさらに深めるために、単一の Employee エンティティを見ているとしましょう。Employee と M:1 の関係を持つ Project エンティティがあります (1 人の従業員が複数のプロジェクトを持つことができます)。特定の従業員に新しいプロジェクトを追加したい場合は、次のようにします。

myEmployee.Projects.Add(new Project());

すばらしい、これは実際にプロジェクトをコレクションに追加します。しかし、これは、ObjectSet プロパティがコンテキストから離れてどのように機能するかという問題に真っ向から直面しています。新しいプロジェクトをコンテキストに追加すると:

myContext.Projects.AddObject(new Project());

これは Projects セットを変更しません。

誰かが私にこれを説明してくれたら、とてもありがたいです。また、コンテキスト内のすべての従業員 (またはプロジェクト) のコレクションが本当に必要であり、コンテキストのプロパティとして利用できるようにしたいと考えています。これはEFで可能ですか?

4

1 に答える 1

16

AnObjectSetはクエリです。LINQのすべてのように、それは怠惰です。列挙するか、のようなメソッドを呼び出すまでは何も実行されません。.Count()その時点でデータベースクエリが実行され、返されたエンティティはすべてコンテキスト内のエンティティとマージされます。

したがって、次のようなことができます。

var activeEmployees = Context.Employees.Where(e => e.IsActive)

...クエリを実行せずに。

これをさらに構成することができます:

var orderedEmployees = activeEmployees.OrderBy(e => e.Name);

...繰り返しますが、クエリを実行しません。

しかし、セットを調べると、次のようになります。

var first = orderedEmployees.First();

...次に、DBクエリが実行されます。これはすべてのLINQに共通です。

ObjectStateManagerすでにコンテキスト内にあるエンティティを列挙する場合は、代わりに、に目を向ける必要があります。したがって、従業員の場合、次のことができます。

var states = EntityState.Added || EntityState.Deleted || // whatever you need
var emps = Context.ObjectStateManager.GetObjectStateEntries(states)
                                     .Select(e => e.Entity)
                                     .OfType<Employee>();

これは機能しますが、私が推奨する方法ではないことに注意してください。通常、ObjectContextを長期間使用することは望ましくありません。このため、およびその他の理由から、これらはオブジェクトの汎用コンテナとしてはあまり適していません。そのために通常のリストタイプを使用します。ObjectContextを作業の単位と考える方が正確です。通常、作業単位では、作業しているインスタンスがすでにわかっています。

于 2010-04-26T20:31:43.590 に答える