LINQでInclude()は何をしますか?


93

私は多くの研究を試みましたが、私はよりdbの人です-したがって、MSDNでの説明でさえ、私には意味がありません。誰もが説明して、クエリに関してどのようなInclude()ステートメントがSQL実行されるかについていくつかの例を提供できますか?


非常に基本的で、単純なSelect、Where、Order by、一部の集約演算子のみを知っています。LINQでJOINを試したことも、Includeしたこともありません。私の最終的な目標は、これらのLINQクエリをSQLに書き直すことでした
CJ

回答:


165

たとえば、すべての顧客のリストを取得するとします。

var customers = context.Customers.ToList();

そして、各Customerオブジェクトがのセットへの参照を持ち、OrdersそれぞれOrderがを参照するLineItems可能性のある参照を持っていると仮定しましょうProduct

ご覧のとおり、多くの関連エンティティを持つトップレベルのオブジェクトを選択すると、クエリが発生し、多くのソースからデータを取得する必要があります。パフォーマンス測定としてInclude()、同じクエリの一部としてデータベースから読み取る必要がある関連エンティティを指定できます。

同じ例を使用すると、関連する注文ヘッダーはすべて含まれますが、他のレコードは含まれません。

var customersWithOrderDetail = context.Customers.Include("Orders").ToList();

SQLを要求してからの最後のポイントとして、最初のステートメントを含まないInclude()単純なステートメントを生成できます。

SELECT * FROM Customers;

呼び出す最後のステートメントは次のInclude("Orders")ようになります。

SELECT *
FROM Customers JOIN Orders ON Customers.Id = Orders.CustomerId;

1
ありがとうございました。あなたの例を使用して、LineItemsand も含めたい場合Productsは、LINQクエリは次のようになりますvar customersWithOrderDetail = context.Customers.Include("Orders").Include("LineItems").Include("Products").ToList();
CJ

2
はい、複数の呼び出しをチェーンしInclude()て、異なる「パス」に沿ってオブジェクトをキャプチャできます。同じパスにオブジェクトが必要な場合は、パス全体を指定する1つの呼び出しを行うだけで済みます。パスコンポーネントを共有LineItemsしてProductsいないため、個別の呼び出しが必要です。
Yuck

インクルードの使用は必須ですか?私はそれを使用せずに関連オブジェクトを取得できるソリューションに取り組んだと確信しています。
Jepzen

@Jepzen遅延読み込みエンティティを使用しているかどうかによって異なります。
Yuck

@Yuck、これは遅延読み込みを使用しているときに機能すると思います。熱心な読み込みの場合、 "include"ステートメントを使用する必要はありませんが、これは明らかにパフォーマンスの問題を引き起こします。これを訂正してください。
2016年

27

「インクルード」は熱心なロードの一部であることを追加したかっただけです。MicrosoftによるEntity Framework 6チュートリアルで説明されています。ここにリンクがあります:https : //docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/reading-related-data-with-the -entity-framework-in-an-asp-net-mvc-application


リンク先のページからの抜粋:

Entity Frameworkが関連データをエンティティのナビゲーションプロパティにロードできるいくつかの方法を次に示します。

遅延読み込み。エンティティが最初に読み取られるとき、関連データは取得されません。ただし、ナビゲーションプロパティに初めてアクセスしようとすると、そのナビゲーションプロパティに必要なデータが自動的に取得されます。その結果、複数のクエリがデータベースに送信されます。1つはエンティティ自体に対するクエリで、もう1つはエンティティの関連データを取得する必要があるたびです。DbContextクラスは、デフォルトで遅延読み込みを有効にします。

熱心な読み込み。エンティティが読み込まれると、関連するデータも一緒に取得されます。通常、これにより、必要なすべてのデータを取得する単一の結合クエリが生成されます。Includeメソッドを使用して、eager loadingを指定します。

明示的な読み込み。これは、関連するデータをコードで明示的に取得することを除いて、遅延読み込みに似ています。ナビゲーションプロパティにアクセスしても、自動的には発生しません。エンティティのオブジェクト状態マネージャーエントリを取得し、コレクションのCollection.Loadメソッドまたは単一のエンティティを保持するプロパティのReference.Loadメソッドを呼び出すことにより、関連データを手動でロードします。(次の例では、アドミニストレーターのナビゲーションプロパティをロードする場合はCollection(x => x.Courses)Reference(x => x.Administrator)。)一般的に、あなたが遅延読み込みをオフにしてきた場合にのみ、明示的なロードを使用すると思います。

プロパティ値はすぐには取得されないため、遅延読み込みと明示読み込みはどちらも遅延読み込みとも呼ばれます。


3
SOへようこそ=)ただの提案ですが、そのようなことに答えるときは、可能であれば、コードスニペットを含めてください。リンクは残念ながら死んでしまう可能性があります。
The_Cthulhu_Kid 2017年

2

それがなければサブアイテムがレイジーローディングになるシナリオでEager-Loadingを強制すると考えてください。

クエリEFがデータベースに送信すると、最初はより大きな結果が得られますが、アクセス時に、含まれているアイテムにアクセスするときにフォローアップクエリは行われません。

一方、これがない場合、EFは後でサブアイテムに最初にアクセスしたときに、別のクエリを実行します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.