This inspection detects the N+1 Select problem, where unnecessary database calls are made when iterating a collection.
The problem can be illustrated with the following example, where Products and Details are 2 database tables and each Product entry is linked to multiple Detail entries.
// First DB query: get all 'Product' entries from the databasevar products = dbContext.Products;// Iterating 'Product' entries in memoryforeach(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}}
To fix this problem, ReSharper suggests using the Include feature of the Entity Framework Core, which will load all linked Detail entries right in the first query:
// Gets all 'Product' and all linked 'Detail' entries from the databasevar products = dbContext.Products.Include(x => x.Details);// Iterating 'Product' entries in memoryforeach(var product in products){// Accessing linked items with 'product.Details' in memoryforeach(var detail in product.Details){// Do something}}
If the chain of navigational property calls is longer, the quick-fix will add ThenInclude as required:
// Gets all 'Product', all linked 'Detail', and all linked 'Line' entries from the databasevar products = dbContext.Products.Include(x => x.Details).ThenInclude(x => x.Lines);// Iterating 'Product' entries in memoryforeach(var product in products){// Accessing linked items with 'product.Details' in memoryforeach(var detail in product.Details){// Accessing linked items with 'detail.Lines' in memoryforeach(var line in detail.Lines){// Do something}}}
note
Using multi-level Include/ThenInclude calls may lead to a cartesian explosion (depending on your database configuration). You may want to consider adding the AsSplitQuery() method to your query when using Entity Framework Core.