Rule Definition
Using .Include() to load many or deep navigation properties:
- Generates large SQL JOINs
- Increases query complexity and size
- Causes duplication in result sets (Cartesian explosion)
- Wastes memory by loading unnecessary data
This leads to significant performance issues, especially when loading related collections (1:N or N:N relationships).
Remediation
Only load what you actually need. Don’t include navigation properties unless they are required by your logic or UI.
You can also project to a DTO.
Violation Code Sample
var order = dbContext.Orders
.Include(o => o.Customer)
.Include(o => o.ShippingAddress)
.Include(o => o.OrderLines)
.Include(o => o.Payments) // ⚠️ VIOLATION : use of multiple Include()
.FirstOrDefault(o => o.Id == id);
Fixed Code Sample
// Load necessary
var order = dbContext.Orders
.Include(o => o.OrderLines) // ✓ FIXED : only one .Include()
.FirstOrDefault(o => o.Id == id);
// Or project to a DTO
var order = dbContext.Orders
.Where(o => o.Id == id)
.Select(o => new OrderDto { // ✓ FIXED : projection to a DTO
Id = o.Id,
Total = o.Total,
CustomerName = o.Customer.Name
}).FirstOrDefault();
Reference
https://learn.microsoft.com/en-us/ef/core/querying/related-data/eager
https://learn.microsoft.com/en-us/ef/core/querying/single-split-queries
https://learn.microsoft.com/en-us/ef/core/performance/
Related Technologies
Technical Criterion
CWE-664 - Improper Control of a Resource Through its Lifetime [Pillar]
About CAST Appmarq
CAST Appmarq is by far the biggest repository of data about real IT systems. It's built on thousands of analyzed applications, made of 35 different technologies, by over 300 business organizations across major verticals. It provides IT Leaders with factual key analytics to let them know if their applications are on track.