我有一个Exercise对象,它有一个ID和一个Category。为了这个问题的目的,让我们假设它看起来像这样:
public class Exercise
{
public int ID;
public string category;
}
ID是唯一的,类别不是。
我想使用Linq按类别对练习进行分组,然后根据ID对每个类别中的练习进行排序。类别的顺序也应该基于ID,第一个练习的类别应该始终是对练习分组后的第一个类别。(换句话说,组的顺序应该由每个组中第一个对象的ID决定,这些ID的顺序应该与组的顺序匹配。)
示例:
{ ID: 1, category: "C#" }
{ ID: 2, category: "ASP" }
{ ID: 3, category: "C#" }
ID为1和3的对象应该在ID为2的对象之前,尽管ASP按字母顺序在C#之前。
这是我的LINQ代码:
_db.Exercise.GroupBy(item => item.category)
.OrderBy(group => group.FirstOrDefault().ID)
.SelectMany(group => group)
.ToList();
它将练习按我期望的方式分组,但无论我做什么,分组的顺序都是按字母顺序排列的。我希望分组上的OrderBy能对分组进行排序,但遗憾的是。
我试着把OrderBy放在不同的地方,但没有成功。此外,仅使用OrderBy似乎也不起作用。将ID和类别都作为关键字的GroupBy似乎也不起作用。
有人能帮我吗?这是我第一次在LINQ中尝试这种"高级"的东西。提前谢谢。
您只需按ID
排序,然后按Category
:分组即可获得所需内容
_db.Exercise.OrderBy(item => item.ID)
.GroupBy(item => item.category)
.SelectMany(group => group)
.ToList();
结果:
List<> (3 items)
ID category
---- ---------
1 C#
3 C#
2 ASP
由于根据文档,组按键在列表中出现的顺序返回,因此将根据每个组中的第一个ID对组进行排序。
正如@Servy所指出的,由于组的顺序是一个实现细节,您可以显式地对组进行排序:
_db.Exercise.OrderBy(item => item.ID)
.GroupBy(item => item.category)
.OrderBy(g => g.First().ID)
.SelectMany(group => group)
.ToList();
当您在IEnumerable<IGrouping<...>>
上调用OrderBy
时,您正在对组进行排序。听起来你想做的是让所有的组按相同的顺序排列,然后将每个组投影到一个新的组中,在该组中对项目进行排序。使用Select
将每个组投影到一个新组,然后使用OrderBy
对组本身进行排序:
var query = _db.Exercise.GroupBy(item => item.category)
.Select(group => group.OrderBy(item => item.ID));
另一方面,如果您只想先按类别订购,然后按ID订购,只需使用OrderBy
和ThenBy
:
var query = _db.Exercise.OrderBy(item => item.category)
.ThenBy(item => item.ID);
groupId
-具有相同类别的所有练习的最低ID
一旦你有了,这就是的一个简单订单
var query = from e in _db.Exercise
let groupId = _db.Exercise.Where(x => x.category == e.category).Select(x => x.ID).Min()
order by groupId, e.ID
select e;
这应该可以做到:
List<Exercise> selectMany = _db.Exercise.GroupBy(exercise => exercise.category)
.SelectMany(grouping =>
grouping.OrderBy(e => e.ID))
.ToList();