是否有可能合并在C#字符串和DBNull的?
-
20-09-2019 - |
题
我正在写一个C#程序调用存储过程。在我传递的参数列表,它是可能的值中的一个可以合法地为空。所以我想我会用这样的行:
cmd.Parameters.Add(new SqlParameter("@theParam", theParam ?? DBNull.Value));
不幸的是,这将返回以下错误:
CS0019:运算符 '?'可以不适用于类型“串”和“System.DBNull”
的操作数
现在,这似乎不够清楚,但我不明白它背后的理念。为什么会这样不行? (通常,当我不明白为什么有什么不工作,这不是它的无法的工作......这是我做错了。)
我真的要舒展了这一点成为一个较长的if-then语句?
编辑:(顺便说一句,这些建议只使用“空”的是,它不工作,我本来想出空会自动翻译成DBNull的太多,但它显然。不。(谁知道?))
解决方案
不是那样的,没有。该类型必须匹配。同样是真实的三元
现在,通过“匹配”,我不是说他们必须是相同的。但他们必须转让兼容。基本上:在相同的继承树
要解决这个问题的一个方法是投你的字符串对象:
var result = (object)stringVar ?? DBNull.Value;
但我不喜欢这样,因为这意味着你更多地依赖于SqlParameter的构造函数来得到你的类型的权利。相反,我喜欢做这样的:
cmd.Parameters.Add("@theParam", SqlDbTypes.VarChar, 50).Value = theParam;
// ... assign other parameters as well, don't worry about nulls yet
// all parameters assigned: check for any nulls
foreach (var p in cmd.Parameters)
{
if (p.Value == null) p.Value = DBNull.Value;
}
还请注意,我明确声明的参数类型。
其他提示
new SqlParameter("@theParam", (object)theParam ?? DBNull.Value)
在??运算符返回左边的操作数,如果它不为空,否则将返回右操作数。但是,在你的情况下,他们是不同类型的,所以这是行不通的。
在空聚结操作者只用相同类型的数据。您不能发送NULL到SqlParamater,因为这将使得SQL服务器说,你没有指定的参数。
可以使用
new SqlParameter("@theParam", (object)theParam ?? (object)DBNull.Value)
或者你可以创建一个返回的DBNull空时发现,像
函数public static object GetDataValue(object o)
{
if (o == null || String.Empty.Equals(o))
return DBNull.Value;
else
return o;
}
和然后调用
new SqlParameter("@theParam", GetDataValue(theParam))
您不能使用空COALESCE操作符的原因是,它必须返回一个类型和所提供不止一种类型。 theParam
是一个字符串。 DbNull.Value
是类型 System.DbNull 一的静态实例的引用>。这是它的实现看起来像;
public static readonly DBNull Value = new DBNull();
//the instantiation is actually in the
//static constructor but that isn't important for this example
所以,如果你有一个NullCoalesce方法,将它的返回类型是什么呢?它不能同时System.String和System.DbNull,它必须是一个或另一个,或一个公共的父类。
因此,导致这种类型的代码;
cmd.Parameters.Add(
new SqlParameter("@theParam", (object)theParam ?? (object)DBNull.Value)
);
在您的存储过程在声明传入变量,有它设置了var等于空,然后不从CSHARP代码,通过它,它就会拿起从SQL的默认值
@theParam as varchar(50) = null
和然后在CSHARP
if (theParam != null)
cmd.Parameters.Add(new SqlParameter("@theParam", theParam));
这是如何我通常通过选项和/或默认的值,以我的存储的特效
我敢肯定,只是路过一个空在它的SqlParameter构造结果发送作为DBNull.Value ......我可能是错的,因为我使用DB访问EnterpriseLibraries,但我敢肯定在发送空是细那里。
cmd.Parameters.Add(新的SqlParameter( “@ theParam”,(theParam == NULL)DBNull.Value:theParam));
使用以下语法:
(theParam作为对象)?? (DBNull.Value作为对象)
在这种情况下,操作者的两个部分??是相同类型的。
不知道具体回答你的问题,但这个怎么样?
string.IsNullOrEmpty(theParam) ? DBNull.Value : theParam
或者如果空白是确定
(theParam == null) ? DBNull.Value : theParam