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!
http://msdn.microsoft.com/en-us/library/ty67wk28.aspx
EDIT: 3/30/2021, it's been 9 years since I wrote this question. Finally as of C# 9, this issue is fixed. Ternary expressions now support mixed types so long as they can be implicitly converted.
DBNull represents a nonexistent value returned from the database. 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.
DBNull is a singleton class, which means only this instance of this class can exist. If a database field has missing data, you can use the DBNull. Value property to explicitly assign a DBNull object value to the field.
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.
This is what I found in another thread and it worked great for me:
yourVariable ?? (object)DBNull.Value
I hope it helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With