C# 使用三元语法将参数设置为 DBNull.Value 会出错?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10853191/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Setting parameter to DBNull.Value using ternary syntax gives error?
提问by Jim
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.
我有以下代码来设置一个参数,该参数将在 INSERT 语句中用于在 SQL Server 数据库中设置 VARCHAR 列。我的值对象(名为 ilo)有一个名为 Description 的属性,它被初始化为 String.Empty,然后被设置为从 XML 读取的某个值,或者如果该 XML 元素为空,它就保持为 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.
因此,当插入到数据库中时,如果该属性仍设置为 String.Empty,我希望它插入一个空值。
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.
所以基本上我是说,如果 ilo.Description 等于 string.empty,则将参数设置为 DBNull.Value,否则将其设置为 ilo.Description。
This gives the following error in Visual Studio...
这会在 Visual Studio 中出现以下错误...
Error 141 Type of conditional expression cannot be determined because there is no implicit conversion between 'System.DBNull' and 'string'
错误 141 无法确定条件表达式的类型,因为“System.DBNull”和“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?
我对 WHY 更感兴趣,因为明显的解决方法是只使用 if/else 语句而不是内联(三元)语法?
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!
在这个链接上有一个答案,但我想要一个更好的解释,因为这对我来说似乎不起作用;我会称之为错误!
采纳答案by Anthony Pegram
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'
无法确定条件表达式的类型,因为“System.DBNull”和“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.
字符串不是 DBNull,DBNull 也不是字符串。因此,编译器无法确定表达式的类型。通过对公共基类型(在本例中为object)的强制转换,您可以创建一个场景,在该场景中,编译器可以确定该字符串也可以转换为对象,因此可以将表达式的类型确定为对象,这也非常适合使用您的代码行也期望作为 DbParameter 参数的内容。
回答by Tuan
You get the compilation error because both parts of the ternary expression must be of the same type. The easiest workaround for this particular situation is to cast both to an object:
您会收到编译错误,因为三元表达式的两个部分必须属于同一类型。对于这种特殊情况,最简单的解决方法是将两者都转换为一个对象:
database.AddInParameter(cmd, "@description", DbType.String,
(ilo.Description.Equals(string.Empty)) ?
(object) DBNull.Value :
(object) ilo.Description);
回答by Marlon
Anthony is indeed correct so he should get the correct answer, however here's an extension method because I'm bored...
安东尼确实是正确的,所以他应该得到正确的答案,但是这里有一个扩展方法,因为我很无聊......
public static object NullCheck(this string self)
{
return (string.IsNullOrEmpty(self)) ? (object)DBNull.Value : self;
}
usage in your scenario:
在您的场景中的用法:
database.AddInParameter(cmd, "@description", DbType.String,
ilo.Description.NullCheck());
回答by Sagar
This is what I found in another thread and it worked great for me:
这是我在另一个线程中发现的,它对我很有用:
yourVariable ?? (object)DBNull.Value
I hope it helps.
我希望它有帮助。

