为MVC视图订购实体框架项和子项

时间:2012-01-30 15:39:16

标签: asp.net asp.net-mvc linq entity-framework sql-order-by

如何从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 }有某种语法吗?

相关问题:
Ordering Entity Framework sub-items for EditorFor
C# Entity Framework 4.1 Lambda Include - only select specific included values

3 个答案:

答案 0 :(得分:4)

值得注意的是,其他2个解决方案通过SQL提取数据,然后重新排序内存中的内容,这在查询和后处理期间的性能方面非常浪费。这个解决方案可以通过SQL单独实现,而无需额外的内存步骤。

可以按照第二种方法中的描述完成: How to order child collections of entities in 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);

答案 1 :(得分:3)

你是对的,你不能在Include中使用订单,这并不意味着以这种方式工作。但您可以使用Orders集合上的OrderBy对视图中的结果进行排序。此外,您直接返回结果,不应该是return View(db.Weeks...);

答案 2 :(得分:1)

这样的事情应该有效:

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