クエリは単純ではありません。( Include
s による) 多くの結合が含まれており、さらに重要なことに、特に含まれているナビゲーション プロパティがコレクションである場合、多くの重複データが返される可能性があります: https://stackoverflow.com/a/5522195 /270591
時間のかかる部分は、オブジェクトの実体化と、データベースからの結果が Entity Framework コンテキストに返されるときにエンティティをコンテキストにアタッチすることです。
これは、同じコンテキスト内の 2 番目のクエリが非常に高速であるという測定 (質問へのコメント) によって確認されます。この場合、EF はデータベースに対してクエリを実行しますが、オブジェクトはまだコンテキストにアタッチされているため、オブジェクトを再度具体化する必要はありません。
2 番目のコンテキストで 2 番目のクエリを実行する場合、結果のエンティティは新しいコンテキストにアタッチする必要があります。この手順も低速です (測定によっても確認されます)。
これはおそらく、EF を使用したクエリが実際には遅く、生の SQL クエリと比較して多くのオーバーヘッドが追加されるポイントです。EF は、変更の追跡と、追加の時間を消費するコンテキストでのオブジェクト ID の管理のために準備された多くのデータ構造を作成する必要があります。
パフォーマンスを改善する唯一の方法は、変更追跡を無効にすることです (おそらく、操作には必要ありません)。EF 4.0 では /ObjectContext
次のようになります。
Database DB = new Database();
DB.Entities.Persons.MergeOption = MergeOption.NoTracking;
// MergeOption is in System.Data.Objects namespace
このアプローチを使用する場合、関連するオブジェクトが同じキーを持っている場合でも別のオブジェクトとして作成されることに注意する必要があります。これは、コンテキストにアタッチするとこの重複が回避されるため、変更追跡が有効になっている場合には当てはまりません。
そのため、より多くのオブジェクトがメモリに読み込まれる可能性があります。これが逆効果であり、実際にパフォーマンスがさらに低下するか、またはそれでもパフォーマンスが向上するかは、テストの問題です。