c# - LINQ to SQL - 排序依据、分组依据以及每个组的排序,并带有skip和take

标签 c# linq linq-to-sql entity-framework-6

这是 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/

相关文章:

c# - 如果类更改,是否需要重新编译和重新部署项目中的所有程序集?

c# - 关于装饰器和策略模式 C# 的设计 OOP 问题

c# - 在google身份验证中将用户信息存入数据库

c# - 转换 linq-to-sql 的结果

.NET 应用程序使用的 SQL View 超时

c# - 将 IEnumerable 转换为 EntitySet

c# - 如何为自定义控件设置命名空间

c# - 如何在不使用 LINQ 遍历整个列表的情况下查找 C# 列表中的第一个匹配项?

c# - LINQ to XML - 具有父级属性的自定义对象列表

c# - MonoDevelop 的 LINQ2SQL 替代品