2013-08-31 120 views
9

我想從數據庫中檢索十進制值,我想知道哪些是檢查空值的推薦方法。SqlDataReader最好的方法來檢查空值-sqlDataReader.IsDBNull與DBNull.Value

我在MSDN - DBNull.Value Field上看到此檢查很少使用。

因此,reader.IsDBNull是檢查空值的最佳/最有效的方法嗎?

我創建了2點的方法:

public static decimal? GetNullableDecimal(SqlDataReader reader, string fieldName) 
{ 
    if (reader[fieldName] == DBNull.Value) 
    { 
     return null; 
    } 
    return (decimal)reader[fieldName]; 
} 

public static decimal? GetNullableDecimal_2(SqlDataReader reader, string fieldName) 
{ 
    if (reader.IsDBNull(reader[fieldName])) 
    { 
     return null; 
    } 
    return (decimal)reader[fieldName]; 
} 

大部分領域都將是空的時間。

在此先感謝!

+0

你喜歡哪一個,哪個是最可讀的。然而,值得注意的是,由於第二個中使用'reader.GetOrdinal',所以你的例子並不完全相同。 –

+1

內部語法'reader [fieldName]'被解析爲'reader.GetOrdinal(fieldName)' – Steve

+0

我修改了這個例子,在這兩種情況下都使用reader [fieldName] – diver

回答

27

我不會太在意哪種方法更好,因爲無論是工作還是我以前都在代碼中使用過。

舉例來說,這裏是一個實用的功能,我從我的老項目之一挖出:

/// <summary> 
/// Helper class for SqlDataReader, which allows for the calling code to retrieve a value in a generic fashion. 
/// </summary> 
public static class SqlReaderHelper 
{ 
    private static bool IsNullableType(Type theValueType) 
    { 
     return (theValueType.IsGenericType && theValueType.GetGenericTypeDefinition().Equals(typeof(Nullable<>))); 
    } 

    /// <summary> 
    /// Returns the value, of type T, from the SqlDataReader, accounting for both generic and non-generic types. 
    /// </summary> 
    /// <typeparam name="T">T, type applied</typeparam> 
    /// <param name="theReader">The SqlDataReader object that queried the database</param> 
    /// <param name="theColumnName">The column of data to retrieve a value from</param> 
    /// <returns>T, type applied; default value of type if database value is null</returns> 
    public static T GetValue<T>(this SqlDataReader theReader, string theColumnName) 
    { 
     // Read the value out of the reader by string (column name); returns object 
     object theValue = theReader[theColumnName]; 

     // Cast to the generic type applied to this method (i.e. int?) 
     Type theValueType = typeof(T); 

     // Check for null value from the database 
     if (DBNull.Value != theValue) 
     { 
      // We have a null, do we have a nullable type for T? 
      if (!IsNullableType(theValueType)) 
      { 
       // No, this is not a nullable type so just change the value's type from object to T 
       return (T)Convert.ChangeType(theValue, theValueType); 
      } 
      else 
      { 
       // Yes, this is a nullable type so change the value's type from object to the underlying type of T 
       NullableConverter theNullableConverter = new NullableConverter(theValueType); 

       return (T)Convert.ChangeType(theValue, theNullableConverter.UnderlyingType); 
      } 
     } 

     // The value was null in the database, so return the default value for T; this will vary based on what T is (i.e. int has a default of 0) 
     return default(T); 
    } 
} 

用法:

yourSqlReaderObject.GetValue<int?>("SOME_ID_COLUMN"); 
yourSqlReaderObject.GetValue<string>("SOME_VALUE_COLUMN"); 
+1

太棒了!我只有一個建議對此進行調整..將此GetValue SqlDataReader更改爲GetValue (此IDataRecord – KevinDeus

6

如果你想檢查null和處理它(如相對於檢查null並提醒程序它爲空),可以使用as運算符和空合併運算符??。 所以在我的節目

SqlDataReader dr = cmd.ExecuteReader(); 
while (dr.Read()) 
{ 
    response.Employees.Add(new Employee() { Id = dr["id"] as int? ?? default(int), ImageUrl = dr["Photo"] as string, JobTitle = dr["JobTitle"] as string }); 
} 
+0

整潔的技巧,感謝分享! – Jocie

1

這裏的@Karl安德森的回答一個簡單的版本:

public static class DbHelper 
{ 
    public static T GetValue<T>(this SqlDataReader sqlDataReader, string columnName) 
    { 
     var value = sqlDataReader[columnName]; 

     if (value != DBNull.Value) 
     { 
      return (T)value; 
     } 

     return default(T); 
    } 
} 

甚至:

public static class DbHelper 
{ 
    public static T GetValue<T>(this SqlDataReader sqlDataReader, string columnName) 
    { 
     var value = sqlDataReader[columnName]; 

     return value == DBNull.Value ? default(T) : (T) value; 
    } 
} 

直接鑄造似乎工作只是罰款或者可爲空或不可爲空的類型。

相關問題