Упорядочение элементов Entity Framework и дочерних элементов для представления MVC
Как я могу отсортировать запрос из DbSet и включить дочерние элементы, которые также должны быть отсортированы.
Пример:
У меня есть модель для планирования заказов.
public class Order
{
public virtual int Id { get; set; }
public virtual int? SchedulingOrder { get; set; }
public virtual int? WeekId { get; set; }
public virtual Week Week { get; set; }
}
public class Week
{
public virtual int Id { get; set; }
public virtual DateTime StartDate { get; set; }
public virtual ICollection<Order> Orders { get; set; }
}
...
public DbSet<Week> Weeks { get; set; }
public DbSet<Order> Orders { get; set; }
Тогда метод действия
public ActionResult ShopSchedule()
{
return View(db.Weeks.OrderBy(w => w.StartDate)
.Include(w => w.Orders.OrderBy(o => o.SchedulingOrder))
.ToList());
}
Это не работает, я думаю, из-за природы Include
, Должен ли я создать отдельную модель вида и сопоставить ее с ней? Или есть какой-то способ обойти это прямо в запросе? Есть какой-то синтаксис, когда люди говорят new { left = right, etc }
в запросе?
связанные вопросы:
Заказ подпунктов Entity Framework для EditorFor
C# Entity Framework 4.1 Lambda Include - выбирайте только определенные включенные значения
3 ответа
Вы правы, вы не можете использовать заказы в Включить, это не должно работать таким образом. Но вы можете отсортировать результаты в представлении, используя OrderBy
в коллекции заказов. Кроме того, вы возвращаете результат напрямую, если это не так return View(db.Weeks...)
;
Стоит отметить, что два других решения здесь обрабатывают данные с помощью SQL, а затем переупорядочивают вещи в памяти, что очень расточительно с точки зрения производительности как при выполнении запроса, так и после обработки. Это решение позволяет получить все за один раз, используя только SQL, без дополнительного шага в памяти.
Это можно сделать, как описано во втором подходе здесь: Как упорядочить дочерние коллекции сущностей в EF
Подобно:
db.VendorProducts.Select(p =>
new { Product = p, S = p.Schedules.OrderBy(s => s.From) })
.FirstOrDefault(q => q.Product.Id == id).Product
Поэтому вместо оператора Include вы вызываете связанные данные в анонимном объекте вместе с исходными корневыми данными, которые вы собирались получить, упорядочиваете их в этом подзапросе и, наконец, возвращаете корневые данные. Порядок остается без изменений. Скручено но работает.
Чтобы придерживаться вашего исходного кода:
db.Weeks.Select(w => new { W = w, O = w.Orders.OrderBy(o => o.SchedulingOrder) })
.OrderBy(q => q.W.StartDate).Select(q => q.W);
Примерно так должно работать:
public ActionResult ShopSchedule()
{
var vw = db.Weeks.OrderBy(w => w.StartDate)
.Include(w => w.Orders)
.ToList();
vw.Orders = vw.Orders.OrderBy(o => o.SchedulingOrder).ToList()
return view(vw);
}