LINQ - 根据最后一个子项条件获取父项

本文关键字:条件 获取 最后一个 LINQ | 更新日期: 2023-09-27 18:33:51

我有当前的实体:

学生(身份证,姓名,..)

等级(ID、Student_Id、等级)

一个学生可以有更多的没有成绩。

使用 LINQ(实体框架)如何获取最后一个成绩不同于 10 的所有学生的列表!

我正在尝试:

var students = db.students.Where(c => c.Grades.LastOrDefault().Grade != 10) .ToList(); 

问题是因为我可能没有任何成绩,所以LastOrDefault可以null.

LINQ - 根据最后一个子项条件获取父项

似乎没有人注意到 LINQ to Entities 不支持Last(Ordefault)。所以你必须使用另一种方法:

var students = db.students
                 .Where(c => c.Grades.OrderByDescending(g => g.Date)
                 .FirstOrDefault().Grade != 10).ToList();

我不得不猜测有一些有用的属性,您可以通过它订购等级(Date?您不想依赖于数据库生成它们的顺序。

如注释中所述,null 值不会在 SQL(计算此表达式的语言)中引发异常。

如果您使用的是 C# 6(.NET 4.6 或更高版本),则可以将新的 Elvis 运算符 .? 与 Null 合并运算符一起使用。

var students = db.students.Where(c => c.Grades.LastOrDefault()?.Grade != 10 ?? false).ToList(); 

基本上猫王运算符将返回 null,如果 LastOrDefault() 为空,否则它将返回 Grade 的值

另外两种可能的方法:检查 c.Grades 是否有任何值,或者检查 LastOrDefault() 是否返回 null。方式1:

var students = db.students.Where(c => c.Grades.LastOrDefault() == null ? false : c.Grades.LastOrDefault().Grade != 10).ToList(); 

方式2:

var students = db.students.Where(c => c.Grades.Any() && c.Grades.LastOrDefault().Grade != 10).ToList(); 

在所有 3 种方式中,学生的结果是一个列表,其中每个学生至少有 1 个年级,而最后一个不是 10 个。

您可以在调用Last()之前简单地检查是否存在Grades,如

var students = db.students
    .Where(c => c.Grades.Count() > 0 && c.Last().Grade != 10)
    .ToList()

或者如评论中所述,您可以利用Any()功能

var students = db.students
    .Where(c => c.Grades.Any() && c.Last().Grade != 10)
    .ToList()