SQL Data Reader - handling Null column values

前端 未结 27 2193
甜味超标
甜味超标 2020-11-22 08:53

I\'m using a SQLdatareader to build POCOs from a database. The code works except when it encounters a null value in the database. For example, if the FirstName column in the

相关标签:
27条回答
  • 2020-11-22 09:11

    how to about creating helper methods

    For String

    private static string MyStringConverter(object o)
        {
            if (o == DBNull.Value || o == null)
                return "";
    
            return o.ToString();
        }
    

    Usage

    MyStringConverter(read["indexStringValue"])
    

    For Int

     private static int MyIntonverter(object o)
        {
            if (o == DBNull.Value || o == null)
                return 0;
    
            return Convert.ToInt32(o);
        }
    

    Usage

    MyIntonverter(read["indexIntValue"])
    

    For Date

    private static DateTime? MyDateConverter(object o)
        {
            return (o == DBNull.Value || o == null) ? (DateTime?)null : Convert.ToDateTime(o);
        }
    

    Usage

    MyDateConverter(read["indexDateValue"])
    

    Note: for DateTime declare varialbe as

    DateTime? variable;
    
    0 讨论(0)
  • 2020-11-22 09:12

    IsDbNull(int) is usually much slower than using methods like GetSqlDateTime and then comparing to DBNull.Value. Try these extension methods for SqlDataReader.

    public static T Def<T>(this SqlDataReader r, int ord)
    {
        var t = r.GetSqlValue(ord);
        if (t == DBNull.Value) return default(T);
        return ((INullable)t).IsNull ? default(T) : (T)t;
    }
    
    public static T? Val<T>(this SqlDataReader r, int ord) where T:struct
    {
        var t = r.GetSqlValue(ord);
        if (t == DBNull.Value) return null;
        return ((INullable)t).IsNull ? (T?)null : (T)t;
    }
    
    public static T Ref<T>(this SqlDataReader r, int ord) where T : class
    {
        var t = r.GetSqlValue(ord);
        if (t == DBNull.Value) return null;
        return ((INullable)t).IsNull ? null : (T)t;
    }
    

    Use them like this:

    var dd = r.Val<DateTime>(ords[4]);
    var ii = r.Def<int>(ords[0]);
    int nn = r.Def<int>(ords[0]);
    
    0 讨论(0)
  • 2020-11-22 09:12

    reader.IsDbNull(ColumnIndex) works as many answers says.

    And I want to mention if you working with column names, just comparing types may be more comfortable.

    if(reader["TeacherImage"].GetType() == typeof(DBNull)) { //logic }
    
    0 讨论(0)
  • 2020-11-22 09:12

    and / or use ternary operator with assignment:

    employee.FirstName = rdr.IsDBNull(indexFirstName))? 
                         String.Empty: rdr.GetString(indexFirstName);
    

    replace the default (when null) value as appropriate for each property type...

    0 讨论(0)
  • 2020-11-22 09:13

    As an addition to the answer by marc_s, you can use a more generic extension method to get values from the SqlDataReader:

    public static T SafeGet<T>(this SqlDataReader reader, int col)
        {
            return reader.IsDBNull(col) ? default(T) : reader.GetFieldValue<T>(col);
        }
    
    0 讨论(0)
  • 2020-11-22 09:14

    By influencing from getpsyched's answer, I created a generic method which checks column value by its name

    public static T SafeGet<T>(this System.Data.SqlClient.SqlDataReader reader, string nameOfColumn)
    {
      var indexOfColumn = reader.GetOrdinal(nameOfColumn);
      return reader.IsDBNull(indexOfColumn) ? default(T) : reader.GetFieldValue<T>(indexOfColumn);
    }
    

    Usage:

    var myVariable = SafeGet<string>(reader, "NameOfColumn")
    
    0 讨论(0)
提交回复
热议问题