C# 在LINQ中,如何对来自.Include()的数据执行.OrderBy()?

C# 在LINQ中,如何对来自.Include()的数据执行.OrderBy()?,c#,asp.net-mvc,linq,C#,Asp.net Mvc,Linq,以下是我正在做的: List<Category> categories = db.Categories.Include("SubCategories").OrderBy(c => c.Order).ToList(); 列表类别= db.Categories.Include(“子类别”).OrderBy(c=>c.Order.ToList(); 在我的分类表中有一列名为“Order”,它只包含一个整数,该整数为表提供某种排序顺序 我的“子类别”表中有相同的列 我想知道在

以下是我正在做的:

List<Category> categories = 
  db.Categories.Include("SubCategories").OrderBy(c => c.Order).ToList();
列表类别=
db.Categories.Include(“子类别”).OrderBy(c=>c.Order.ToList();
在我的分类表中有一列名为“Order”,它只包含一个整数,该整数为表提供某种排序顺序

我的“子类别”表中有相同的列

我想知道在我的子类别表中添加排序的最简单解决方案。。。比如:

List<Category> categories = 
  db.Categories.Include("SubCategories").OrderBy(c => c.Order)
     .ThenBy(c => c.SubCategories as x => x.Order).ToList();
列表类别=
db.Categories.Include(“子类别”).OrderBy(c=>c.Order)
.ThenBy(c=>c.SubCategories as x=>x.Order).ToList();
我想保持这种LINQ格式。。。(方法格式)


请记住,我在MVC中工作,需要将其作为模型返回到视图中。由于匿名类型,我一直遇到错误问题…

如果
类别。子类别本身就是一个集合,那么您将无法使用现有的扩展方法进行订购(和
c=>c.SubCategories as x=>x.Order
几乎没有任何意义,基本上说
SubCategories
函数

如果您满足于在内存中完成排序(这应该不是一个问题,因为您已经从数据库中获取了它们,但前提是您并没有成千上万的东西)您可以实现自己的自定义
IComparer
,它查询每个
类别的
子类别
,以确定在排序操作中一个
类别
应放在另一个
类别
的上方还是下方

你的声明将是:

var categories = db.Categories.Include("SubCategories").OrderBy(x => x, new CategorySubCategoryComparer())

您可以将单个查询拆分为两个查询,这两个查询只填充上下文:

IQueryable<Category> categoryQuery = db.Categories.Where(c=> /*if needed*/);
List<Category> categories = categoryQuery.OrderBy(c => c.Order).ToList();
categoryQuery.SelectMany(c => c.SubCategories)
  .OrderBy(sub => sub.Order)
  .AsEnumerable().Count(); // will just iterate (and add to context) all results
IQueryable categoryQuery=db.Categories.Where(c=>/*如果需要*/);
List categories=categoryQuery.OrderBy(c=>c.Order.ToList();
categoryQuery.SelectMany(c=>c.SubCategories)
.OrderBy(sub=>sub.Order)
.AsEnumerable().Count();//将迭代(并添加到上下文)所有结果

您甚至不再需要容易出错的字符串“SubCategories”。

我不确定这是否受支持,但下面是如何实现的:

List<Category> categories = 
  db.Categories.Include(c => c.SubCategories.OrderBy(s => s.Order)).OrderBy(c => c.Order)

Category.SubCategories
是一个集合还是一个实例?也就是说,有许多子类别还是只有一个?它看起来像是基于名称的集合,但如果是这种情况,则需要使用聚合函数(例如Min/Max/Average)在您的
中,ThenBy
。是的,它是一个集合。在一个类别下有许多子类别…这些子类别存储在两个单独的表中,带有从子类别到cat的外键。您不能在linq2entity或Linq2Sql中使用
CategorySubCategoryComparer
。基于Include的用法,我假设OP使用的是实体框架(尽管未指定)。您可以将自定义IComparer与任何IEnumerable一起使用。如果实体框架不够聪明,无法在传递到接受自定义IComparer的OrderBy重载之前执行查询,则OP可以改为执行以下操作:var categories=db.categories.Include(“子类别”).ToList().OrderBy(x=>x,new CategorySubCategoryComparer())是的EF不是智能的,事实上,EF不能将此转换为表达式树以从中进行sql查询,所以首先应该执行它,在这种情况下不是很糟糕,但不是很好。我毫不怀疑任何ORM,EF或不是,都可以解释自定义IComparable并将其转换为sql:)这会将子类别作为一个整体进行排序,而不是考虑它们与每个类别的相关性,不是吗?这会很好,子类别只是按照上下文的顺序附加到其父类别,因此对于每个父类别,其子类别都按顺序属性进行排序。当然,这只会在一个新的环境中起到无副作用的作用——但EF环境应该总是短暂的。但是仔细想想,首先填写类别列表,然后再执行
SelectMany
查询会更安全。
@for (var cat in Model.Categories) {
   @cat.Name
   @for (var sub in cat.SubCategories.OrderBy(c => c.Order) {
       @sub.Name
   }
}