Исключение " ... Выражение пути включения должно ссылаться на свойство навигации ... ", в основном жалуется, что c.Comics.OrderBy
не является свойством навигации. (Думаю, это законная жалоба.)
На самом деле EF не поддерживает применение сортировки (а также фильтрации) в выражениях загрузки (Include
).
Итак, что вы можете сделать?
Вариант 1:
Сортировка в памяти после загрузки объекта:
model.Page = db.Pages
.Where(p => p.PageId == Id)
.Include(p => p.Series.Select(c => c.Comics
.Select(col => col.Collection)))
.SingleOrDefault();
if (model.Page != null)
{
foreach (var series in model.Page.Series)
series.Comics = series.Comics.OrderBy(c => c.ReadingOrder).ToList();
}
Ужасно, но поскольку вы загружаете, по-видимому, только один объект Page
по идентификатору, возможно, он быстрее (LINQ to Objects в памяти), чем следующие параметры (если коллекции Series
и Comics
не слишком длинные).
Вариант 2:
Разбейте запрос на части, которые смешивают энергичную и явную загрузку:
model.Page = db.Pages
.Where(p => p.PageId == Id)
.Include(p => p.Series) // only Series collection is included
.SingleOrDefault();
if (model.Page != null)
{
foreach (var series in model.Page.Series)
db.Entry(series).Collection(s => s.Comics).Query()
.Include(c => c.Collection)
.OrderBy(c => c.ReadingOrder)
.Load(); // one new DB query for each series in loop
}
Вариант 3:
Прогноз
Здесь и здесь - это, кстати, что-то об опасностях сложных Include
цепочек с несколькими навигационными свойствами. Он может загружать огромное количество дублированных данных. Include
гарантирует, что у вас есть только один обход БД, но, возможно, за счет гораздо большего количества передаваемых данных. Явная загрузка имеет несколько циклов обработки, но с общим объемом данных, возможно, меньшим.
(Я знаю, я дал вам эту цепочку Включить ... Выбрать ... Выбрать ... Выбрать ..., но как я узнал, что вы отнесетесь ко мне серьезно :). Ну, в зависимости от размера ваших вложенных коллекций, это все равно может быть лучшим вариантом.)