Упорядочение элементов Entity Framework и дочерних элементов для представления MVC - PullRequest
5 голосов
/ 30 января 2012

Как я могу отсортировать запрос из 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 ]

4 голосов
/ 24 января 2013

Стоит отметить, что два других решения здесь извлекают данные через 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);
3 голосов
/ 30 января 2012

Вы правы, вы не можете использовать заказы в Включить, это не должно работать таким образом. Но вы можете отсортировать результаты в представлении, используя OrderBy в коллекции Orders. Кроме того, вы возвращаете результат напрямую, если это не return View(db.Weeks...);

1 голос
/ 05 февраля 2012

Примерно так должно работать:

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);
}
...