我經常遇到問題處理DataRows
從SqlDataAdapters
返回。當我嘗試填補對象使用這樣的代碼:什麼是最好的方式來處理DBNull的
DataRow row = ds.Tables[0].Rows[0];
string value = (string)row;
什麼是這種類型的情況來處理DBNull's
的最佳途徑。
我經常遇到問題處理DataRows
從SqlDataAdapters
返回。當我嘗試填補對象使用這樣的代碼:什麼是最好的方式來處理DBNull的
DataRow row = ds.Tables[0].Rows[0];
string value = (string)row;
什麼是這種類型的情況來處理DBNull's
的最佳途徑。
可以爲空的類型是好的,但只適用於不能以空格開頭的類型。
爲了一種「可空」問號追加到類型,例如:
int? value = 5;
我也建議使用「as
」關鍵字,而不是鑄造的。您只能在可爲空的類型上使用「as」關鍵字,因此請確保您正在投射已經爲空的東西(如字符串),或者使用上面提到的可空類型。這樣做的原因是
as
」關鍵字返回null
如果值是DBNull
。as
,但加上它的原因是有用的。我建議你做這樣的事情
DataRow row = ds.Tables[0].Rows[0];
string value = row as string;
在上述情況下,如果row
回來爲DBNull
,然後value
將成爲null
,而不是拋出異常。請注意,如果您的數據庫查詢更改了返回的列/類型,使用as
將導致您的代碼在默認情況下失敗並使值簡單null
而不是在返回不正確的數據時拋出相應的異常,因此建議您進行測試以其他方式驗證您的查詢,以確保您的代碼庫發展時的數據完整性。
您也可以用Convert.IsDBNull (MSDN)進行測試。
添加對System.Data.DataSetExtensions
的引用,該引用添加了Linq對查詢數據表的支持。
這將是這樣的:
string value = (
from row in ds.Tables[0].Rows
select row.Field<string>(0)).FirstOrDefault();
+1:這個答案應該是更upvoted大概也接受了 - 絕對row.Field
我平時寫一個封裝內置Convert類我自己ConvertDBNull類。如果該值爲DBNull,則它將返回null(如果其引用類型)或默認值(如果其值類型)。 例子: - ConvertDBNull.ToInt64(object obj)
回報Convert.ToInt64(obj)
除非obj是爲DBNull在這種情況下,如果你不使用可空類型,它將返回0。
,做的最好的事情就是檢查是否該列的值是爲DBNull。如果它是DBNull,那麼設置你對相應的數據類型使用null/empty的引用。
DataRow row = ds.Tables[0].Rows[0];
string value;
if (row["fooColumn"] == DBNull.Value)
{
value = string.Empty;
}
else
{
value = Convert.ToString(row["fooColumn"]);
}
隨着馬努說,你可以創建每個類型的重載轉換方法的轉換類,所以你不if/else語句塊必須辣椒代碼。
但是我會強調,如果你可以使用它們,可以爲空的類型是更好的路徑。理由是,對於非空類型,您將不得不求助於「幻數」來表示空值。例如,如果你將一個列映射到一個int變量,你將如何表示DBNull?通常你不能使用0,因爲在大多數程序中0有一個有效的含義。通常我會看到人們將DBNull映射到int.MinValue,但這可能也有問題。我最好的建議是這樣的:
可以使用可爲空的類型來解決這個問題。話雖如此,如果您使用的是舊版本的框架,或者爲不支持可空類型的人員工作,那麼代碼示例就可以解決這個問題。
行if(行[「fooColumn」] == DBNull.Value)的作品,但不正確。它沒有被定義DBNull.Value應該被實現爲Singleton模式。更好的一行是:if(row [「fooColumn」]是DBNull) – doekman 2009-06-12 08:30:32
@doekman - 實際上,DBNull *是一個單例類。引用MSDN:「DBNull是一個單例類,這意味着只有這個類的[DBNull.Value]實例可以存在。」 http://msdn.microsoft.com/en-us/library/system.dbnull.value.aspx – Greg 2009-12-22 16:39:42
如果你想治療的DBNull爲空字符串行[「fooColumn」]。的ToString()將做到這一點。 – samir105 2012-12-23 08:27:46
出於某種原因,我已經受夠了做對DBNull.Value檢查的問題,所以我已經做過的事情有所差異,DataRow對象中的槓桿屬性:
if (row.IsNull["fooColumn"])
{
value = string.Empty();
}
{
else
{
value = row["fooColumn"].ToString;
}
如果你有控制即返回結果的查詢,你可以使用ISNULL()返回非空值是這樣的:
SELECT
ISNULL(name,'') AS name
,ISNULL(age, 0) AS age
FROM
names
如果你的情況可以容忍這些魔法值代替NULL,採用這種方法可以解決這個問題通過你的整個應用程序,而不會混淆你的碼。
我總是發現使用If/Else檢查版本的清晰,簡潔和無問題,只能使用三元運算符。將所有內容保留在一行上,包括如果列爲空,則分配默認值。
因此,假設名爲「MyCol」一空Int32列,在這裏我們想返回-99如果列空,但返回整數值如果列不爲空:
return row["MyCol"] == DBNull.Value ? -99 : Convert.ToInt32(Row["MyCol"]);
這是與上面的If/Else獲勝者相同的方法 - 但是我發現,如果您從數據讀取器中讀取多列,這是一個真正的獎勵,所有列讀線都排在一起,排列整齊,因爲它更容易現場錯誤:
Object.ID = DataReader["ID"] == DBNull.Value ? -99 : Convert.ToInt32(DataReader["ID"]);
Object.Name = DataReader["Name"] == DBNull.Value ? "None" : Convert.ToString(DataReader["Name"]);
Object.Price = DataReader["Price"] == DBNull.Value ? 0.0 : Convert.ToFloat(DataReader["Price"]);
布拉德·艾布拉姆斯發佈有關短短几天前 http://blogs.msdn.com/brada/archive/2009/02/09/framework-design-guidelines-system-dbnull.aspx
總結的東西「避免使用System.DBNull。身高可空來代替。「
這裏是我的兩分錢(未經測試的代碼:))
// Or if (row["fooColumn"] == DBNull.Value)
if (row.IsNull["fooColumn"])
{
// use a null for strings and a Nullable for value types
// if it is a value type and null is invalid throw a
// InvalidOperationException here with some descriptive text.
// or dont check for null at all and let the cast exception below bubble
value = null;
}
else
{
// do a direct cast here. dont use "as", "convert", "parse" or "tostring"
// as all of these will swallow the case where is the incorect type.
// (Unless it is a string in the DB and really do want to convert it)
value = (string)row["fooColumn"];
}
而且一個問題......你沒有使用ORM的原因嗎?
的DBNull實現的ToString() 。像其他一切不需要做任何事情而不是硬投,調用該對象的的ToString()方法
DataRow row = ds.Tables[0].Rows[0];
string value;
if (row["fooColumn"] == DBNull.Value)
{
value = string.Empty;
}
else
{
value = Convert.ToString(row["fooColumn"]);
}
這將成爲:
DataRow row = ds.Tables[0].Rows[0];
string value = row.ToString()
DBNull.ToString()返回的String.Empty
我會想象這是你要找的
值得一提的是,這DBNull.Value.ToString()
等於String.Empty
你可以用你的優勢:
DataRow row = ds.Tables[0].Rows[0];
string value = row["name"].ToString();
然而,這僅適用於絃樂,其他一切我會使用linq方式或擴展方法。至於我自己,我寫了檢查的DBNull一點點擴展方法,並與數據表工作時,即使不通過Convert.ChangeType(...)
int value = row.GetValueOrDefault<int>("count");
int value = row.GetValueOrDefault<int>("count", 15);
通常情況下,鑄造你必須處理這種情況下,如果行字段可以是零或DBNull的,通常我處理,像這樣:
string myValue = (myDataTable.Rows[i]["MyDbNullableField"] as string) ?? string.Empty;
的「爲」經營者返回null無效轉換的,像DBNull的字符串,而「?」如果第一個爲空,則返回 表達式右側的項。
密切:[最高效的單向到檢查換的DBNull和 - 然後,分配到一個變量(http://stackoverflow.com/questions/221582/most-efficient-way -to-檢查換爲DBNull和-然後指派到一個變量) – nawfal 2013-12-11 16:42:38