2008-11-25 75 views
2

我有一個擁有用戶可選配置文件的數據庫。在配置文件中我有字符串,字符(用於M或F)和整數。從SQL數據庫中處理null int/char的最佳做法是什麼?

我遇到了一個問題,我嘗試將用戶的性別放入Profile對象的屬性中,並且應用程序崩潰,因爲它不知道如何處理返回的空值。

我嘗試了數據流延到合適的類型

char sex = (char)dt.Rows[0]["Sex"]; 

這並沒有解決我的問題。然後我嘗試將類型更改爲Nullable和Nullable,並獲得所有相同的轉換問題。我目前能找到的解決方案如下:

object.sex = null; 
if(dt.Rows[0]["Sex"] != DBNull.Value) 
     object.sex = (char)dt.Rows[0]["Sex"]; 
object.WorkExt = null; 
if(dt.Rows[0]["WorkExt"] != DBNull.Value) 
     object.WorkExt = (int)dt.Rows[0]["WorkExt"]; 

有沒有更簡單或更好的方法來做到這一點?還是我在正確的軌道上?

回答

3

rotard的回答(用Is<ColumnName>Null())僅適用於類型化的數據集。

對於無類型的數據集,您必須使用以下代碼中的一種模式。如果此代碼不是確定性的,請告訴我,我將對其進行編輯,直到它爲止。這是一個非常普遍的問題,應該只有一個正確的答案。

using System. 
using System.Data; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     DataTable dt = new DataTable(); 
     dt.Columns.Add("test", typeof (char)); 
     dt.Columns["test"].AllowDBNull = true; 

     DataRow dr = dt.Rows.Add(); 
     char? test; 

     try 
     { 
      test = (char?)dr["test"]; 
     } 
     catch (InvalidCastException) 
     { 
      Console.WriteLine("Simply casting to a nullable type doesn't work."); 
     } 

     test = dr.Field<char?>("test"); 
     if (test == null) 
     { 
      Console.WriteLine("The Field extension method in .NET 3.5 converts System.DBNull to null.");     
     } 

     test = (dr["test"] is DBNull) ? null : (char?) dr["test"]; 
     if (test == null) 
     { 
      Console.WriteLine("Before .NET 3.5, you have to check the type of the column's value."); 
     } 

     test = (dr["test"] == DBNull.Value) ? null : (char?) dr["test"]; 
     if (test == null) 
     { 
      Console.WriteLine("Comparing the field's value to DBNull.Value is very marginally faster, but takes a bit more code."); 
     } 

     // now let's put the data back 

     try 
     { 
      dr["test"] = test; 
     } 
     catch (ArgumentException) 
     { 
      Console.WriteLine("You can't set nullable columns to null."); 
     } 

     dr.SetField("test", test); 
     if (dr["test"] is DBNull) 
     { 
      Console.WriteLine("Again, in .NET 3.5 extension methods make this relatively easy."); 
     } 

     dr["test"] = (object)test ?? DBNull.Value; 
     if (dr["test"] is DBNull) 
     { 
      Console.WriteLine("Before .NET 3.5, you can use the null coalescing operator, but note the awful cast required."); 
     } 


     Console.ReadLine(); 
    } 
} 
0

我會和你一樣做。我會寫一個函數爲它:

的東西做:

object.sex = handle(dt.Rows[0]["Sex"]); 

在手柄你做的== DBNull.Value檢查。

+0

這只是工作,如果你的函數返回一個對象,你投返回值爲char?在任務中。 .NET 3.5的DataRow擴展中的Field方法爲您做到這一點。 – 2008-11-25 22:26:15

1

dt是一個ADO.Net 2數據表嗎?你不能這樣做:

if(dt.Rows[0].IsSexNull()) {} else {} 

?另外,假設你可以控制你的數據庫,那麼使用一點而不是一個字符串會更有意義嗎?

+0

有些人不知道如何回答這個問題,有些人不喜歡告訴你。你可以將這些組合在一起,但至少需要第三個選項。 – 2008-11-25 20:15:57

+0

真,假或空ftw – Jimmy 2008-11-25 22:40:08

3

可空類型是專爲此目的而設計的!用'as char?'而不是 '(字符?)'

class Foo { 
    char? sex; 
} 
Foo object; 

object.sex = dt.Rows[0]["Sex"] as char?; 
1

怎麼樣:

internal static T CastTo<T>(object value) 
    { 
     return value != DBNull.Value ? (T)value : default(T); 
    } 

,然後用它喜歡:

 return new EquipmentDetails(
      CastTo<int>(reader["ID"]), 
      CastTo<int>(reader["CategoryID"]), 
      CastTo<string>(reader["Description"])); 

等等

相關問題