Bước đầu là nhìn SQL thật, không đoán.
EF Core có simple logging bật trong vài dòng:
optionsBuilder
.LogTo(Console.WriteLine, LogLevel.Information)
.EnableSensitiveDataLogging(); // dev onlyDấu hiệu N+1 rất dễ nhận: sau một SELECT danh sách là hàng loạt SELECT giống hệt nhau chỉ khác giá trị tham số trong WHERE.
EnableSensitiveDataLogging ghi cả giá trị tham số — hữu ích khi debug nhưng không bật ở production vì log sẽ chứa dữ liệu người dùng.
Nguyên nhân phổ biến nhất là lazy loading: mỗi lần chạm navigation property trong vòng lặp là một round-trip.
foreach (var order in orders)
total += order.Customer.Discount; // one query per orderCách sửa: Include để eager load, hoặc tốt hơn là Select sang DTO để EF sinh một câu JOIN duy nhất.
Ở production, nơi không bật log verbose được, dùng Microsoft.EntityFrameworkCore.Database.Command ở mức Information trong structured logging, hoặc APM (Application Insights, OpenTelemetry) để xem số DB call trên mỗi request.