2016-02-09 52 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

列表