The DBNull type is a very special type in .NET. It represents null values in databases, which are slightly different than null values in .NET.
The biggest confusion that people have with it is that it won’t convert to anything. Which means that you see a lot of questions like “System.InvalidCastException: Conversion from type ‘DBNull’ to type” “is not valid”.
You’d think the full name would be System.Data.DBNull, it is actually named System.DBNull. The reason is that various other functionality of the System namespace depend on it, for instance the System.Convert class.
DBNull was already present in .NET 1.x, so it predates nullable types that were introduced in C# 2 / .NET 2.
A null value on the database side will result in a DBNull instance.
If you want to explicitly pass a null value to a database, you use a DBNull.Value, which is a singleton.
Why DBNull
There is a very interestin question/answer series on StackOverflow about this: via .net – What is the point of DBNull? – Stack Overflow.
There are a few good arguments both for and against DBNull.
But the baseline is that DBNull predates the introduction in the .NET framework of genuine nullable types. Both their behaviour is slightly different, so DBNull had to stay.
Which means you have to deal with it every now and then.
Invalid casts
A bit more background on the invalid casts.
It is thrown like this:
throw new InvalidCastException(Environment.GetResourceString("InvalidCast_DBNull"));
from
Convert.DefaultToType();
which is called from the DBNull method
object IConvertible.ToType(Type type, IFormatProvider provider);
All other IConvertible methods are implementated like
bool IConvertible.ToBoolean(IFormatProvider provider)
{
throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromDBNull"));
}
So these all throw the same exception:
bool IConvertible.ToBoolean(IFormatProvider provider);
byte IConvertible.ToByte(IFormatProvider provider);
char IConvertible.ToChar(IFormatProvider provider);
DateTime IConvertible.ToDateTime(IFormatProvider provider);
decimal IConvertible.ToDecimal(IFormatProvider provider);
double IConvertible.ToDouble(IFormatProvider provider);
short IConvertible.ToInt16(IFormatProvider provider);
int IConvertible.ToInt32(IFormatProvider provider);
long IConvertible.ToInt64(IFormatProvider provider);
sbyte IConvertible.ToSByte(IFormatProvider provider);
float IConvertible.ToSingle(IFormatProvider provider);
ushort IConvertible.ToUInt16(IFormatProvider provider);
uint IConvertible.ToUInt32(IFormatProvider provider);
ulong IConvertible.ToUInt64(IFormatProvider provider);
–jeroen
via:
Like this:
Like Loading...