2010-07-15 58 views
1

我有一個LINQ2SQL查詢,看起來像這樣:這真的是一個可能的InvalidOperationException?

var data = from d in dc.GAMEs 
    where (d.GAMEDATE + d.GAMETIME.Value.TimeOfDay) >= DateTime.Now 
     && d.GAMESTAT == 'O' && d.GAMETYPE == 0 select d; 

ReSharper的是強調在藍色的「d.GAMETIME.Value.TimeOfDay」,並告訴我,這是一個可能System.InvalidOperationException。雖然我知道,如果它是C#代碼,引用值而不檢查它是否有值會是這樣,我不知道這是否是一個Linq查詢是真的。

實際生成的SQL看起來非常可怕,並且讓我想灼傷我的眼睛,但是我看不到任何看起來可能是空引用的東西。我可以放心地忽略這個嗎?

(暫時忽略其他問題,如它返回預期的結果)

編輯:

在進一步的思考,我可以看到上面可能會導致異常的LinqToObjects查詢,還有其他類型(XML?)。所以是的,我想Resharper只是在安全。

回答

2

當處理表達式樹(如LINQ to SQL查詢)時,它完全依賴於使用的LINQ提供程序(在您的情況下爲LINQ to SQL)。因此,Resharper對您的查詢說出任何有用的信息幾乎是不可能的。我認爲它只是將這些代碼解釋爲正常的C#代表。我可以說忽略它是安全的,但也許會爲下一個開發人員添加評論。

0

沒有看到數據模式,我的猜測是GAMETIMENullable<DateTime> - 即映射到DB中可以爲空的日期時間/時間字段。 Resharper只是簡單地給你一個靜態分析警告,指出你在檢查Nullable<T>.Value時沒有檢查它是否有價值。

您可以通過這種方式重新編寫查詢:

var data = from d in dc.GAMEs 
    where (d.GAMEDATE + (d.GAMETIME.HasValue ? d.GAMETIME.TimeOfDay : new TimeSpan())) >= DateTime.Now 
     && d.GAMESTAT == 'O' && d.GAMETYPE == 0 select d; 

上面的查詢只需要使用的0時間跨度時GAMETIME爲NULL。

考慮到GAMEDATE是一個不可爲空的數據庫字段,並且GAMETIME是可爲空的數據庫字段,我建議您將GAMETIME設置爲不可空的。這樣兩個字段是一致的,不需要額外的邏輯來處理NULL值。

編輯我剛纔已經證實,試圖調用Nullable<T>.Value確實拋出InvalidOperationException,不NullReferenceException

horse's mouth(粗體是礦):

的兩個 可空結構的基本構件是的HasValue 和Value屬性。如果Nullable對象的HasValue 屬性爲 爲true,則可以使用Value屬性訪問該對象的值 。 如果 HasValue屬性是false,則對象的 值是未定義和 訪問Value 屬性會引發 InvalidOperationException異常的嘗試。

+0

我沒有對數據庫結構的控制權,它被第三方工具使用並且必須符合它們的模式。 FWIW,GAMEDATE也是可以空的,但沒有必要訪問任何成員,因爲它是隱含的。另外,你的修改並不是真正的同一個查詢,因爲沒有時間的gamedate只能在今天進行比較,而不是現在。 – 2010-07-15 21:11:10

+0

正確的是,與今天相比是後備。在你的表單中,當GAMETIME爲NULL時,它就會崩潰。 – 2010-07-15 23:55:52