c# - LINQ 用于获取每个不同名称的 5 条最新记录
问题描述
我一直在尝试从“名称”列中具有不同名称的数据库中获取 5 条最新记录。这意味着我想要表中每个唯一名称的 5 条最新记录。
这是一个示例表:
id | Name | Status | Start | End <br />
1 | Bob | Pass | 2020-01-01 | 2020-01-01<br />
2 | Chris | Pass | 2020-01-01 | 2020-01-02<br />
3 | James | Fail | 2020-01-01 | 2020-01-03<br />
4 | Bob | Pass | 2020-01-01 | 2020-01-04<br />
5 | Chris | Fail | 2020-01-01 | 2020-01-05<br />
6 | Bob | Pass | 2020-01-01 | 2020-01-06<br />
7 | Bob | Fail | 2020-01-01 | 2020-01-07<br />
8 | Bob | Fail | 2020-01-01 | 2020-01-08<br />
9 | Chris | Pass | 2020-01-01 | 2020-01-09<br />
10 | Bob | Pass | 2020-01-01 | 2020-01-10<br />
我希望返回最新的 5 条 Bob 记录(共 6 条)、3 条 Chris 记录和 1 条 James 记录。
到目前为止,我已经尝试过以下方法:
- 将其分为两个不同的操作:查询 Distinct 名称,然后根据名称查询,通过 endDate 获取最新的 5 条记录并附加到列表中。使用这种方法,我能够正确执行第一个查询。我打印出三个不同的名字(Bob、Chris、James)。但是,每次我使用这些名称进行查询并获取 5 条最新记录时,所有三个名称都会返回为空。根据 Visual Studio 2019,我尝试进行的任何打印都表示变量名无效......所以我尝试了方法 2
// GET: api/Student/latestRecords
[HttpGet("latestRecords")]
public async Task<ActionResult<IEnumerable<Student>>> GetLatestRecordsOnAllStudent()
{
var distinctStudentNames = _context.Students.Select(x => x.name).Distinct();
IQueryable<Student> allRecords = new Student[] { }.AsQueryable();
foreach (string studentName in distinctStudentNames)
{
var newList = _context.Students.OrderByDescending(x => x.endTime).DistinctBy(y => y.name).Select( z => z).Take(5);
allRecords.Concat(newList);
}
return allRecords.ToList();*/
}
- 使用单个 LINQ 查询。使用这种方法,我能够根据名称获得 3 条不同的记录,但我无法获得比这更多的记录。
// GET: api/Student/latestRecords
[HttpGet("latestRecords")]
public async Task<ActionResult<IEnumerable<Student>>> GetLatestRecordsOnAllStudents()
{
var distinctStudentsNames = _context.Students.DistinctBy(x => x.name).OrderByDescending(x => x.endTime).Select(z => z).Take(5).ToList();
return distinctStudentsNames;
}
如果方法 2 可行,我会喜欢它,但我觉得我可能会踩到自己的脚趾,试图在一个电话中完成所有操作。如果有人有一些建议,将不胜感激。
解决方案
编辑:
正如@NetMerge 指出的那样,这在 EF Core 中不起作用,所以我暂时将答案留在这里,以防 OP 无论如何都想看看它。
这是一个示例类,其中只有我们关注的两个属性和您的示例列表。
public class Student
{
public string Name { get; set; }
public DateTime End { get; set; }
}
var students = new List<Student>
{
new Student() { Name = "Bob", End = new DateTime(2020, 1, 1) },
new Student() { Name = "Chris", End = new DateTime(2020, 1, 2) },
new Student() { Name = "James", End = new DateTime(2020, 1, 3) },
new Student() { Name = "Bob", End = new DateTime(2020, 1, 4) },
new Student() { Name = "Chris", End = new DateTime(2020, 1, 5) },
new Student() { Name = "Bob", End = new DateTime(2020, 1, 6) },
new Student() { Name = "Bob", End = new DateTime(2020, 1, 7) },
new Student() { Name = "Bob", End = new DateTime(2020, 1, 8) },
new Student() { Name = "Chris", End = new DateTime(2020, 1, 9) },
new Student() { Name = "Bob", End = new DateTime(2020, 1, 10) }
};
你可以先做一个GroupBy()
然后属性,然后从每个中取 5 个OrderByDescending()
。End
var recentFiveForEachName = students
.GroupBy(x => x.Name, (key, g) => g.OrderByDescending(y => y.End).Take(5));
推荐阅读
- sql - 在 SQL 中将重复分组为批次
- java - Integer.parseInt() 和 Integer.toString() 运行时
- java - Java - 避免将对象引用传递给多个地方,同时确保其线程安全
- python - Plotly:如何将水平滚动条添加到 plotly express 图形?
- laravel - Laravel:强制刷新扩展视图
- javascript - 在 Javascript 中创建嵌套数组
- c# - 如何修复:CS1061 错误。我将如何创建属性?
- javascript - Check if all arrays in an object are equal to all arrays in another object
- python - Bitbucket 部署不支持基于 s3 的 lambda 函数
- python - 使用字符串格式化python的列