関連テーブルのレコードが LINQ2SQL で読み込まれるのはいつですか
-
21-08-2019 - |
質問
2 つのテーブルがあるとします。
- 報告
- コメント
そして、データベースコンテキストがあると仮定します。
var reports = db.Reports();
各レポートのすべてのコメントも確実に読み込まれるようにするにはどうすればよいですか?
この時点で、データベースから切断したいが、それでもコメントにアクセスできます。(例えば:)
reports[0].Comments[0].Subject
解決
レポートとコメントの間には 1-M FK の関係があると仮定しています (1 つのレポートには多数のコメントを含めることができます)。
1 つのオプションは、 DataLoadOptions.LoadWith メソッド - 次のようなもの:
var reports = db.Reports();
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<Reports>(r => r.Comments); // Ask for Comments along with reports
reports.LoadOptions = dlo;
これで、そのデータ コンテキストに関するレポートを選択するたびに、コメントも一緒にデータベースから取得されます。
コメントのすべてのフィールドが選択されることに注意してください。このメソッドを使用してフィールドのサブセットを選択することはできません。
もう 1 つのオプションは、Linq クエリで何を選択するかを具体的に指定することです。
var myReportsList = from report in db.Reports
select new { // Using anonymous type, but could use a custom class
Report = report,
Comment = report.Comment.Detail, // for example
Subject = report.Comment.Subject
};
クエリがいつ実行され、データベース接続が閉じられるかを理解するには、次のことを理解する必要があります。
- Linq および Linq To Sql の遅延実行モデル (基本的に、Linq to SQL の場合、クエリは結果が要求された場合にのみ実行されます。コレクションを反復処理するか、グリッドにバインドすることによって)
- IQueryable と IEnumerable の違い
Jon Skeets の「C# in Depth」では、これらについての素晴らしい概要が説明されています。また、「Linq in Action」についても非常に良いことを聞いています。さらに、これらの概念については、私ができる以上に正確に主題を説明しているブログ記事がたくさんあります。ここで;o)
他のヒント
LoadOptions を使用してマルチホップ パス (レポート、コメント、別のエンティティ) を定義する場合、3 番目以降のホップは (1:n の関係で関連している場合) コードによって読み込まれるため、非常に非効率であることに注意してください。親ごとに 1 つのクエリを実行します。レポートとコメントの場合は問題ありません。2 つのクエリで取得されます。