實體框架在記錄上調用MAX為null

entity-framework

在IQueryable上調用Max()並且沒有記錄時,我得到以下異常。

轉換為值類型“Int32”失敗,因為實現值為null。結果類型的泛型參數或查詢必須使用可空類型。

var version = ctx.Entries
    .Where(e => e.Competition.CompetitionId == storeCompetition.CompetitionId)
    .Max(e => e.Version);

現在我明白為什麼會發生這種情況我的問題是如果表格可以為空,那麼最好的方法是如何做到這一點。下面的代碼可以解決這個問題,但是它的醜陋是否沒有MaxOrDefault()概念?

int? version = ctx.Entries
    .Where(e => e.Competition.CompetitionId == storeCompetition.CompetitionId)
    .Select(e => (int?)e.Version)
    .Max();

一般承認的答案

是的,轉換為Nullable of T是處理LINQ to Entities查詢中的問題的推薦方法。擁有一個具有正確簽名的MaxOrDefault()方法聽起來像一個有趣的想法,但是你只需要為每個提出這個問題的方法提供一個額外的版本,這個版本不能很好地擴展。

這是CLR中的工作方式與它們在數據庫服務器上的實際工作方式之間的許多不匹配之一。 Max()方法的簽名已經這樣定義,因為結果類型應該與CLR上的輸入類型完全相同。但是在數據庫服務器上,結果可以為null。出於這個原因,您需要將輸入(儘管取決於您編寫查詢的方式,可能足以將輸出強制轉換)轉換為Nullable of T.

這是一個看起來比上面簡單的解決方案:

var version = ctx.Entries 
    .Where(e => e.Competition.CompetitionId == storeCompetition.CompetitionId) 
    .Max(e =>(int?)e.Version);

希望這可以幫助。


熱門答案

嘗試此操作為最大值創建默認值。

int version = ctx.Entries 
    .Where(e => e.Competition.CompetitionId == storeCompetition.CompetitionId) 
    .Max(e =>(int?)e.Version) ?? 0;


Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因