質問

I have a nullable DateTime field "BirthDate" the existing code was handeling this in such a way

info.BirthDate = (DateTime?)reader["Birthdate"];

This causes an "Invalid Cast" error and it breaks. Ok, I understand this is because nulls are returned differently from sql and are of the type "DBNull"

Fix for this turned out to be

if (reader["Birthdate"] != DBNull.Value)
{
    info.Birthdate = (DateTime)reader["Birthdate"];
}

Can someone explain why exactly this works?..I'm particularly lost on the .Value part of DBNull. If it IS returning as DBNull how does the code even reach inside this block?

役に立ちましたか?

解決

DBNull is a singleton. There is only one instance of it. You access this instance with DBNull.Value. The comparison checks if DBNull(.Value) is returned and if it is not returned (!=) then it knows it can safely cast it to a DateTime.

From MSDN:

DBNull is a singleton class, which means only this instance of this class can exist.

Alternatively you could use the Convert.IsDBNull method:

if (!Convert.IsDBNull(reader["Birthdate"]))
{
    info.Birthdate = (DateTime)reader["Birthdate"];
}

他のヒント

DBNull is a type, not a value. As @aKzenT explained, it is implemented as a singleton, meaning there can only only be one instance of that type. The way to get to that one value is through the static .Value property.

This makes it easy to do comparisons since any DBNull instance is equal in both value and reference to another DBNull instance.

Another way to do that check which may make more sense is:

int columnIndex = reader.GetOrdinal("Birthdate");
if (!reader.IsDbNull(columnIndex)) // IsDbNull should have a string overload, but it does not.
{
    info.Birthdate = (DateTime)reader["Birthdate"];
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top