Выбор ответа Middle EF Core обновлено

Декартов взрыв при нескольких Include

Вопрос

Запрос db.Orders.Include(o => o.Items).Include(o => o.Payments) медленный на больших заказах. В чём причина и как исправить?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Декартово произведение items × payments, нужен AsSplitQuery(). По умолчанию EF Core строит один запрос с JOIN всех коллекций.

Варианты ответа

  1. Include всегда выполняет отдельный запрос на каждую строку
  2. EF Core не поддерживает несколько Include в одном запросе
  3. Нужно заменить Include на ленивую загрузку коллекций
  4. Декартово произведение items × payments, нужен AsSplitQuery()правильный ответ

Разбор

По умолчанию EF Core строит один запрос с JOIN всех коллекций. Если у заказа 50 позиций и 10 платежей, для него вернётся 500 строк с дублированием данных. AsSplitQuery() разбивает загрузку на отдельные запросы по коллекциям, их число фиксировано и не зависит от числа строк. Ленивая загрузка вернёт проблему N+1. Несколько Include поддерживаются.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.