C# 为什么SqlParameter名称/值构造函数将0视为null?
我在一段代码中发现了一个奇怪的问题,即席SQL查询没有生成预期的输出,即使其参数与数据源中的记录匹配。我决定在即时窗口中输入以下测试表达式:C# 为什么SqlParameter名称/值构造函数将0视为null?,c#,sql-server,ado.net,sqlparameter,C#,Sql Server,Ado.net,Sqlparameter,我在一段代码中发现了一个奇怪的问题,即席SQL查询没有生成预期的输出,即使其参数与数据源中的记录匹配。我决定在即时窗口中输入以下测试表达式: new SqlParameter("Test", 0).Value 这导致了null,这让我挠头。似乎SqlParameter构造函数将零视为空值。以下代码生成正确的结果: SqlParameter testParam = new SqlParameter(); testParam.ParameterName = "Test"; testParam.Va
new SqlParameter("Test", 0).Value
这导致了null
,这让我挠头。似乎SqlParameter
构造函数将零视为空值。以下代码生成正确的结果:
SqlParameter testParam = new SqlParameter();
testParam.ParameterName = "Test";
testParam.Value = 0;
// subsequent inspection shows that the Value property is still 0
有人能解释这种行为吗?这是故意的吗?如果是这样,则可能相当危险…如该构造器的:
在value参数中指定对象时,SqlDbType将从该对象的Microsoft.NET Framework类型推断出来
使用构造函数的此重载指定整型参数值时请小心。由于此重载接受类型的值,因此必须在值为零时将整数值转换为类型,如下C#示例所示
Parameter = new SqlParameter("@pname", (object)0);
如果不执行此转换,编译器将假定您正在尝试调用构造函数重载
您只是调用了一个与您在本例中想象的不同的构造函数
原因是C允许从整数文本0
隐式转换为枚举类型(下面只是整数类型),这种隐式转换导致(字符串,SqlDbType)
构造函数比将(字符串,对象)
构造函数的int
转换为对象所需的装箱转换更适合重载解析
当您传递int
变量时,即使该变量的值为0
(因为它不是零文本)或任何其他类型为int
的表达式,这也不会成为问题。如果如上所示将int
显式强制转换为对象
,也不会发生这种情况,因为这样只有一个匹配重载。在传递/添加参数时使用类型化数据是一种好做法
您可以通过以下方式完成以下任务:
对于字符串/varchar类型的数据:
SqlParameter pVarchar = new SqlParameter
{
ParameterName = "Test",
SqlDbType = System.Data.SqlDbType.VarChar,
Value = string.Empty,
};
SqlParameter pInt = new SqlParameter
{
ParameterName = "Test",
SqlDbType = System.Data.SqlDbType.Int,
Value = 0,
};
对于整型数据:
SqlParameter pVarchar = new SqlParameter
{
ParameterName = "Test",
SqlDbType = System.Data.SqlDbType.VarChar,
Value = string.Empty,
};
SqlParameter pInt = new SqlParameter
{
ParameterName = "Test",
SqlDbType = System.Data.SqlDbType.Int,
Value = 0,
};
您可以根据使用的数据更改SqlDbType
的值。虽然通常很有用,但从技术上讲,这并不是问题的答案。进一步阅读这个主题:我遇到了这个问题,并尝试了另一个不起作用的解决方案:为什么建议的Parameter=newsqlparameter(“@pname”,Convert.ToInt32(0))当参数=新的SqlParameter(“@pname”,(int)0)时,代码>工作代码>我试过了没有?@mortb,你必须查阅语言规范,但我的猜测是,重载解析在第一种情况下会考虑确切的类型,但在第二种情况下可能会允许枚举,因为您仍在传递类型为int
的文本。我发现了原因:文本0将始终被计算为与枚举的类型匹配,而其他数字则不会。似乎有点模糊…引用的示例有点问题:Convert.ToInt32(0)
不会更改所选的重载。代码应该是newsqlparameter(“@pname”,(object)0)
@Steven:如果我错了,请纠正我,但是只有文本0
可以隐式转换为任何枚举类型。因此,返回int
的方法调用很好,并选择另一个重载。诚然,我已经有几个月没有看过这个规范了,但我相信它是这样工作的。