Простой сценарий Category
и Product
(один ко многим). Category
имеет поле Description
, которое может быть длинным текстом. Теперь мне нужно запросить список категорий со всеми их продуктами. Явная загрузка документации упоминает два очевидных подхода, которые не подходят в моем случае (см. Ниже).
Мой подход
var categories = await dc.Categories
.AsNoTracking()
.ToListAsync();
var catDict = categories.ToDictionary(q => q.Id);
var catIds = catDict.Keys;
var products = await dc.Products
.Where(q => catIds.Contains(q.CategoryId))
.ToListAsync();
foreach (var product in products)
{
// Category.Products is initialized with empty List already
catDict[product.CategoryId].Products.Add(product);
}
Этот подход требует только два запроса и делает не иметь избыточных данных. Я по-прежнему счастлив, даже если EF Core может вытащить JOIN, но вместо этого выбрать только Id
из Category
.
Есть ли в EF Core какой-либо метод / команда / запрос, который просит его запросить связанные данные таким образом ?
Другие упомянутые подходы:
1 подход к запросу
var categories = await dc.Categories
.AsNoTracking()
.Include(q => q.Products)
.ToListAsync();
Этот генерирует только один вызов БД, но слишком много избыточных данных:
Подход N + 1 запросов
var categories = await dc.Categories
.AsNoTracking()
.ToListAsync();
foreach (var category in categories)
{
category.Products = await dc.Products
.Where(q => q.CategoryId == category.Id)
.ToListAsync();
}
Этот подход удаляет избыточные данные, но теперь есть вызовы N + 1 DB.