Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Possible to use ?? (the coalesce operator) with DBNull?

If I have code similar to the following:

while(myDataReader.Read())
{
  myObject.intVal = Convert.ToInt32(myDataReader["mycolumn"] ?? 0);
}

It throws the error:

Object cannot be cast from DBNull to other types.

defining intVal as a nullable int is not an option. Is there a way for me to do the above?

like image 821
Abe Miessler Avatar asked Feb 24 '12 19:02

Abe Miessler


People also ask

Is DBNull value the same as null?

Null is similar to zero pointer in C++. So it is a reference which not pointing to any value. DBNull. Value is completely different and is a constant which is returned when a field value contains NULL.

What does DBNull value mean?

The DBNull class represents a nonexistent value. In a database, for example, a column in a row of a table might not contain any data whatsoever. That is, the column is considered to not exist at all instead of merely not having a value. A DBNull object represents the nonexistent column.

What is use of NULL coalesce operator?

Uses of Null Coalescing Operator: It is used to replace the ternary operator in conjunction with the PHP isset() function. It can be used to write shorter expressions. It reduces the complexity of the program. It does not throw any error even if the first operand does not exist.


6 Answers

Here's one more option:

while (myDataReader.Read())
{
    myObject.intVal = (myDataReader["mycolumn"] as int? ?? 0);
}
like image 180
Edyn Avatar answered Sep 23 '22 06:09

Edyn


Can you use an extension method? (written off the top of my head)

public static class DataReaderExtensions 
{
    public static T Read<T>(this SqlDataReader reader, string column, T defaultValue = default(T))
    {
        var value = reader[column];

        return (T)((DBNull.Value.Equals(value))
                   ? defaultValue
                   : Convert.ChangeType(value, typeof(T)));
    }
}

You'd use it like:

while(myDataReader.Read())
{
  int i = myDataReader.Read<int>("mycolumn", 0);
}
like image 31
Bryan Boettcher Avatar answered Sep 25 '22 06:09

Bryan Boettcher


Can you simply use Int32.Tryparse?

int number;
bool result = Int32.TryParse(myDataReader["mycolumn"].ToString(), out number);

According to the MSDN, number will contain 0 if the conversion failed

like image 27
Morphed Avatar answered Sep 22 '22 06:09

Morphed


How about something like:

object x = DBNull.Value;
int y = (x as Int32?).GetValueOrDefault(); //This will be 0

Or in your case:

int i = (myDataReader["mycolumn"] as Int32?).GetValueOrDefault();
like image 44
Mike Christensen Avatar answered Sep 25 '22 06:09

Mike Christensen


Why not use something other than the null coalescing operator (DBNull.Value != null):

int i = myDataReader["mycolumn"] == DBNull.Value ?
            Convert.ToInt32(myDataReader["mycolumn"]) :
            0;

You could always wrap it up in a neat extension method:

public static T Read<T>(this DataReader reader, string column, T defaultVal)
{
    if(reader[column] == DBNull.Value) return defaultVal;
    return Convert.ChangeType(reader[column], typeof(T));
}
like image 36
Justin Niessner Avatar answered Sep 24 '22 06:09

Justin Niessner


Nope, only works for nulls.

How about an extension method on object that checks for DBNull, and returns a default value instead?

//may not compile or be syntactically correct! Just the general idea.
public static object DefaultIfDBNull( this object TheObject, object DefaultValue )
{
    if( TheObject is DBNull )
        return DefaultValue;
    return TheObject;
}
like image 34
asawyer Avatar answered Sep 24 '22 06:09

asawyer