如何从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
答案 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);
}