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?
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);
}
Here's one more option:
while (myDataReader.Read())
{
myObject.intVal = (myDataReader["mycolumn"] as int? ?? 0);
}
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
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();
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));
}
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;
}