コードインスペクション: 関連エンティティに対してデータベースへ複数回クエリが実行される可能性 (N+1 問題)
このインスペクションは、コレクションを反復するときに不必要なデータベース呼び出しが行われる N+1 セレクト問題を検出します。
この問題は次の例で説明できます。 Products と Details は 2 つのデータベーステーブルで、各 Product エントリは複数の Detail エントリに紐づいています。
// First DB query: get all 'Product' entries from the database
var products = dbContext.Products;
// Iterating 'Product' entries in memory
foreach (var product in products)
{
// Accessing linked items with 'product.Details'
// generates a new DB query for each 'Product',
// which makes it N queries + the first query.
foreach (var detail in product.Details)
{
// Do something
}
}
この問題を解決するために、ReSharper は Entity Framework Core の Include 機能を使うことを提案しています。これにより、すべての関連付けられた Detail エントリが最初のクエリで読み込まれます:
// Gets all 'Product' and all linked 'Detail' entries from the database
var products = dbContext.Products.Include(x => x.Details);
// Iterating 'Product' entries in memory
foreach (var product in products)
{
// Accessing linked items with 'product.Details' in memory
foreach (var detail in product.Details)
{
// Do something
}
}
ナビゲーションプロパティ呼び出しのチェーンが長い場合、クイックフィックスは必要に応じて ThenInclude を追加します。
// Gets all 'Product', all linked 'Detail', and all linked 'Line' entries from the database
var products = dbContext.Products.Include(x => x.Details).ThenInclude(x => x.Lines);
// Iterating 'Product' entries in memory
foreach (var product in products)
{
// Accessing linked items with 'product.Details' in memory
foreach (var detail in product.Details)
{
// Accessing linked items with 'detail.Lines' in memory
foreach (var line in detail.Lines)
{
// Do something
}
}
}
2026 年 6 月 12 日