2016-02-09 55 views
1

我目前的实体:LINQ - 基于最后一个孩子病情得到父母

学生(ID,姓名,..)

等级(ID,student_id数据,级)

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

使用LINQ(实体框架)我怎样才能得到所有学生的最后一个档次不同于10的列表!

我尝试:

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

的问题是,因为我可能没有任何等级,LastOrDefault可以null

+1

'问题是因为我可能没有任何成绩,所以LastOrDefault可能为空。“如果这是LINQ到对象,那么这很重要,但是使用EF将被转换为SQL,并且SQL传播空值,而不是抛出NRE。 – Servy

+1

没有成绩的学生会被计算在内吗?比如,“没有成绩”是否意味着算作“最后”的成绩!= 10或者不是?此外,您需要清楚“最后一级”是什么意思 - 如果它是基于某个日期或最高ID的最新的或类似的东西,您必须确保使用'OrderBy'来确保'LastOrDefault '得到正确的记录! – SlimsGhost

回答

3

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

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

我猜测,没有通过它您可以订购的成绩了一些有用的特性。您不想依赖数据库碰巧产生它们的顺序。

正如评论中所说的,空值不会在SQL中引发异常,而SQL是评估此表达式的语言。

1

你可以简单地检查的Grades存在调用Last()像以前一样

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() 
+1

'Where where(c => c.Grades.Any()&& c.Last()。Grade!= 10)'利用'Any()'函数 – Rodolfo

1

的优势使用C#6(.NET 4.6或更高版本),您可以使用新的Elvis Operator。与Null合并运算符一起使用。

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

基本上Elvis操作符将返回null,如果LastOrDefault()为空,否则它将返回甲级

其他两个可能的方法的价值: 检查是否有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

列表