我正在尋找一些.net程序的代碼,我正在處理。該程序的前一作者在一年前向我提供了代碼。突然,我看到從代碼中拋出的異常,我沒有感動:關於空字符串和DBNull的困惑
if ((string)row["LevelName"] != "ABC")
唯一的例外是「無法投類型的對象'System.DBNull爲鍵入‘System.String’
。我認爲字符串是一個可空數據類型,所以我怎麼可能會得到這個異常
我正在尋找一些.net程序的代碼,我正在處理。該程序的前一作者在一年前向我提供了代碼。突然,我看到從代碼中拋出的異常,我沒有感動:關於空字符串和DBNull的困惑
if ((string)row["LevelName"] != "ABC")
唯一的例外是「無法投類型的對象'System.DBNull爲鍵入‘System.String’
。我認爲字符串是一個可空數據類型,所以我怎麼可能會得到這個異常
DBNull是它自己的類,它包含itsself在一個名爲Value屬性singleton實例。 DBNull.Value不等於null,因爲它是對此類的實例的引用。
如果沒有值,大多數(即使不是全部)數據庫包裝將返回DBNull.Value
而不是null
。其中一個原因是因爲返回一個真實的null
可能意味着根本不存在任何行,而不僅僅是列中的空值(這取決於您使用哪些對象來獲取值)。
通常,as運算符對於DBNull
非常有用,可以與任何可空類型(包括string
)一起使用。
string str = reader["Name"] as string;
int? i = reader["Age"] as int?;
這也可能是值得一提的是,??運營商是非常有用的也在這裏,當你需要一個非空值類型(雖然它不看太漂亮)。
int i = reader["Age"] as int? ?? -1;
我發現這很方便,因爲它是LINQ select子句中的一件小事。
我相信你要找的是什麼?
if ((row["LevelName"] as String) != "ABC")
沒有隱式轉換DBNull和String之間。
它可能以前工作過,因爲剛好在您的數據庫中該列中沒有NULL。也許有些數據被破壞,或者有人在表上改變了NOT NULL約束。
基本上,如果您明確施放了某些東西,最好確保它們具有兼容的動態類型,否則會拋出異常。 as
操作員基本上說「如果可能的話將其轉換爲此值,否則邏輯值爲空。」顯然,as
運算符只能用於引用類型,因爲結構不能爲空。
你的答案暗示了這一點,但值得說明的是:在使用顯式類型轉換'(Type)變量'會導致'InvalidCastException'的情況下,使用'variable as Type'將產生'null'。 – Rob
.NET null
與DBNull.Value
之間存在差異。在這裏,您可以看到類DBNull
和該類的Value字段。
你應該能夠做這樣的事情:
if (row["LevelName"].Value == DBNull.Value)
return false;
else if (row["LevelName"].ToString() != "ABC")
// do something
// ....
DBNull表示數據庫中的空值。這與.NET null不同,它表示一個空引用。
代碼突然失敗,因爲有人更改或插入了空白的記錄。
是的,字符串可以爲空,但是您將一個dbnull投射到字符串。您必須檢查dbnull,如果它存在,則將其替換爲null。
DBNull表示在給定的數據庫列中沒有數據。如果在數據庫中創建新記錄,但沒有將值分配給「LevelName」列,則會發生這種情況。
DBNull與空對象引用或空字符串變量不同。 DBNull表示列數據從未設置。如果您爲「LevelName」列指定一個空值,那麼該列已經初始化並且它將返回null(而不是DBNull)。
此代碼已運行良好超過一年;我覺得我一定在某個地方弄錯了什麼 –
是的,事實上,我做到了。有問題的代碼沒有準備好DBNull值,因爲它永遠不會出現在我正在運行的特定查詢中。我在修改查詢時犯了一個錯誤,因此錯誤出現了。 –
感謝您提供豐富的答案,每個人。我把它們都投了票。難怪我讀的SQL書叫NULL「四個字母的單詞」。 –