这是 Jon Skeet 已回答问题的扩展,您可以 find here.
期望的结果如下:
A 100
A 80
B 80
B 50
B 40
C 70
C 30
考虑到您有以下类(class):
public class Student
{
public string Name { get; set; }
public int Grade { get; set; }
}
要得到结果(在理想情况下)可以通过 Jon Skeet 的答案来完成:
var query = grades.GroupBy(student => student.Name)
.Select(group =>
new { Name = group.Key,
Students = group.OrderByDescending(x => x.Grade) })
.OrderBy(group => group.Students.FirstOrDefault().Grade);
但是就我而言,我还必须在查询中支持分页。这意味着执行SelectMany(),然后执行Skip()和Take()。但要执行Skip(),您必须应用OrderBy()。这是我的排序再次中断的地方,因为我需要保留 SelectMany() 之后得到的顺序。
如何实现这一目标?
var query = grades.GroupBy(student => student.Name)
.Select(group =>
new { Name = group.Key,
Students = group.OrderByDescending(x => x.Grade) })
.OrderBy(group => group.Students.FirstOrDefault().Grade).SelectMany(s => s.Students).OrderBy(something magical that doesn't break ordering).Skip(s => skip).Take(t => take);
我知道当我的查询具体化时,我可以手动再次对记录进行排序,但我想避免这种情况,并在从 LINQ 翻译的一个 SQL 查询中完成所有这些操作。
最佳答案
您可以采用另一种方法,即使用 Max
,而不是对每个组进行排序并采用第一个值。之后,您可以按最高成绩、姓名(如果两个学生的最高成绩相同)和成绩进行排序:
var query = c.Customers
.GroupBy(s => s.Name, (k, g) => g
.Select(s => new { MaxGrade = g.Max(s2 => s2.Grade), Student = s }))
.SelectMany(s => s)
.OrderBy(s => s.MaxGrade)
.ThenBy(s => s.Student.Name)
.ThenByDescending(s => s.Student.Grade)
.Select(s => s.Student)
.Skip(toSkip)
.Take(toTake)
.ToList();
EF6 支持所有这些方法,因此您应该会得到您想要的结果。
关于c# - LINQ to SQL - 排序依据、分组依据以及每个组的排序,并带有skip和take,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50630639/