В любом случае требовать от EF Core использования двух запросов для связанных данных вместо 1 или N+1?C#

Место общения программистов C#
Ответить
Anonymous
 В любом случае требовать от EF Core использования двух запросов для связанных данных вместо 1 или N+1?

Сообщение Anonymous »

Простой сценарий категории и продукта (один ко многим). Категория имеет поле «Описание», которое может содержать длинный текст. Теперь мне нужно запросить список категорий со всеми их продуктами. В документации по явной загрузке упоминаются два очевидных подхода, которые не подходят в моем случае (см. ниже).
Мой подход

Код: Выделить всё

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, но вместо этого выберет только идентификатор категории.
Есть ли какой-либо метод/команда/запрос в EF Core который просит его запрашивать связанные данные таким образом?
Это должно быть похоже на явную загрузку, но если есть метод, который можно применить к списку объектов:

Код: Выделить всё

    await context.Collection(categories) // instead of context.Entry(...) for a single entity
.Collection(b => b.Products)
.LoadAsync();
Другие упомянутые подходы:
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.

Подробнее здесь: https://stackoverflow.com/questions/611 ... -of-1-or-n
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»