I have the following bit of code to set a parameter that will be used in an INSERT statement to set a VARCHAR column in a SQL Server database. My value object (named ilo) has a property called Description that gets initialized to String.Empty, and then either gets set to some value read from XML, or if that XML element is empty it just stays as String.Empty.
So when inserting into the database, if the property is still set to String.Empty, I'd like to have it insert a null value.
database.AddInParameter(cmd, "@description", DbType.String,
(ilo.Description.Equals(string.Empty)) ?
DBNull.Value :
ilo.Description);
So basically I'm saying, if ilo.Description equals string.empty, set the parameter to DBNull.Value, otherwise set it to ilo.Description.
This gives the following error in Visual Studio...
Error 141 Type of conditional expression cannot be determined because there is no implicit conversion between 'System.DBNull' and 'string'
Why?
The curious part is that I can do the following with no error, which should be exactly the same thing as using inline conditional syntax like above!?!
if(ilo.Description.Equals(string.Empty))
{
database.AddInParameter(cmd, "@description", DbType.String, DBNull.Value);
}
else
{
database.AddInParameter(cmd, "@description", DbType.String, ilo.Description);
}
I searched other posts, and found the one below, but it doesn't really answer my question.
EntLib Way to Bind "Null" Value to Parameter
I'm more interested in WHY, because the obvious workaround is to just use an if/else statement instead of the inline (ternary) syntax?
There's sort of an answer at this link, but I'd like a better explanation because it seems to be BS to me that this doesn't work; I'd call it a bug!
This is a common error people receive when using the conditional operator. To fix it, simply cast one or both of the results to a common base type.
ilo.Description.Equals(string.Empty)
? (object)DBNull.Value
: ilo.Description
The issue is revealed in the error message you saw.
Type of conditional expression cannot be determined because there is no implicit conversion between 'System.DBNull' and 'string'
A string is not a DBNull, and a DBNull is not a string. Therefore, the compiler cannot determine the type of the expression. By using a cast to a common base type (in this case, object
), you create a scenario where the compiler can then determine that string is also convertible to object, so the type of the expression can be determined as object, which also nicely fits with what your line of code also expects as the DbParameter argument.