Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use datareader with null values

Say I have this class:

class myclass
{
    public int Field1{ get; set; }
    public int? Field2 { get; set; } //Note Field2 is nullable
 }

I'm trying to populate a generic list with data coming from a database. As GetSqlInt32 implements INullable I would have thought that the below code would work. It doesn't. It generates an error if Field2 is null.

List<myclass> mylist=new List<myclass>();

int Field1_Ordinal = rdr.GetOrdinal("Field1");
int Field2_Ordinal = rdr.GetOrdinal("Field2");

SqlDataReader rdr = cmd.ExecuteReader(); //Execute a stored procedure to retrieve data from the database

while (rdr.Read())
 {
   mylist.Add(new myclass
   {
      Field1 = rdr.GetSqlInt32(Field1_Ordinal).Value,
      Field2 = rdr.GetSqlInt32(Field2_Ordinal).Value  //Error if field2 is null
   });
 }

Any ideas why it doesn't work?

like image 660
Anthony Avatar asked Sep 01 '09 13:09

Anthony


People also ask

How do I handle null in DataReader?

Handling Null column values using turnery operator: In this example I used turnery operator with DBNull. Value to check sql data reader columns value is null or not, if found null then column value assigned to some default value.

How do you check if a DataReader is null or empty?

GetValue(0) != DbNull. Value) //if value in columnA is not null { //.... } }

How do you accept null values?

The NULL value can cause problems when selecting data. However, because when comparing an unknown value to any other value, the result is always unknown and not included in the results. You must use the IS NULL or IS NOT NULL operators to check for a NULL value.

How does ado net handle null value?

For working with database ANSI SQL null values, use System. Data. SqlTypes nulls rather than Nullable. For more information on working with CLR value nullable types in Visual Basic see Nullable Value Types, and for C# see Nullable value types.


4 Answers

It seems to me that you need a conversion like this (using an extension method for convenience):

public static int? ToNullableInt32(this SqlInt32 value)
{
    return value.IsNull ? (int?) null : value.Value;
}

Then:

Field2 = rdr.GetSqlInt32(Field2_Ordinal).ToNullableInt32()

(Comment on other answers: there's no need to bring DbNull into this, as SqlInt32 can already represent null values. You just need to detect that before using Value.)

like image 132
Jon Skeet Avatar answered Oct 04 '22 05:10

Jon Skeet


Check out this solution which wasn't written by me:

employee.FirstName = sqlreader[indexFirstName] as string;
employee.Age = sqlreader[indexAge] as int? ?? default(int);

It was originally proposed here:

SQL Data Reader - handling Null column values

like image 21
Ignacio Soler Garcia Avatar answered Oct 04 '22 03:10

Ignacio Soler Garcia


Here's a pain reduction variation on the theme. If someone knows how to merge Val and Ref into one template function fell free to post. You will have to state the type explicitly (C# compiled can't be bothered :-) but this:

var dd = r.Val<DateTime>(ords[4]);
var ii = r.Def<int>(ords[0]);
int nn = r.Def<int>(ords[0]);

is still maked my fingers happy :-)

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;
}
like image 43
ZXX Avatar answered Oct 04 '22 03:10

ZXX


I think it is beacuse the value returned is DBNull.Value, and not null.

Instead you can use the IsDbNull() method to check if the field is null before reading it.

like image 21
Rune Grimstad Avatar answered Oct 04 '22 05:10

Rune Grimstad