2013-03-14 81 views
2

我有一個可空DateTime字段「出生日期」的現有代碼以這樣的方式解釋處理DBNull?

info.BirthDate = (DateTime?)reader["Birthdate"]; 

這會導致「無效的轉換」錯誤和它打破了這個HANDELING。好吧,我明白這是因爲空值從SQL返回不同,是類型「DBNull的」

定爲這竟然是

if (reader["Birthdate"] != DBNull.Value) 
{ 
    info.Birthdate = (DateTime)reader["Birthdate"]; 
} 

有人能解釋到底爲什麼這個工程?我特別是在DBNull的.Value部分丟失了。如果它返回爲DBNull IS代碼甚至可以在這個塊內到達嗎?

回答

4

DBNull是一個單身人士。它只有一個實例。您可以使用DBNull.Value訪問此實例。比較檢查是否返回DBNull(.Value),如果沒有返回(!=),則知道它可以安全地將其轉換爲DateTime

MSDN

的DBNull是一個單獨的類,這意味着這個 類的只有這個實例可以存在。

另外,您可以使用Convert.IsDBNull方法:

if (!Convert.IsDBNull(reader["Birthdate"])) 
{ 
    info.Birthdate = (DateTime)reader["Birthdate"]; 
} 
+0

.... OH。好吧,因爲這個屬性是可以空的,所以它沒有任何內容,並且這個塊被跳過。我現在明白了。謝謝! – Evr 2013-03-14 15:58:22

+0

第三個選項是'reader [「Birthdate」]作爲DateTime?'。 (對第三種選擇有有效的反對意見,並且也有贊成的有效論據,我寧願避免這樣的討論:)) – hvd 2013-03-14 15:58:23

+0

啊,對了,會的。說我可以在4分鐘內。這是我第一篇帖子SO – Evr 2013-03-14 16:01:31

0

DBNull是一個類型,而不是一個。正如@aKzenT所解釋的那樣,它是作爲單例實現的,這意味着該類型只能有一個實例。達到該值的方法是通過靜態.Value屬性。

這使得它容易做比較,因爲任何DBNull實例的值和參考另一個DBNull實例都是相等的。

另一種方式來做到這一點支票可能更有意義的是:

int columnIndex = reader.GetOrdinal("Birthdate"); 
if (!reader.IsDbNull(columnIndex)) // IsDbNull should have a string overload, but it does not. 
{ 
    info.Birthdate = (DateTime)reader["Birthdate"]; 
} 
+0

謝謝你的補充澄清!..很高興我決定在這裏發帖,而不是無知地想。 – Evr 2013-03-14 16:06:35