Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么SqlParameter名称/值构造函数将0视为null?_C#_Sql Server_Ado.net_Sqlparameter - Fatal编程技术网

C# 为什么SqlParameter名称/值构造函数将0视为null?

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

我在一段代码中发现了一个奇怪的问题,即席SQL查询没有生成预期的输出,即使其参数与数据源中的记录匹配。我决定在即时窗口中输入以下测试表达式:

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
的方法调用很好,并选择另一个重载。诚然,我已经有几个月没有看过这个规范了,但我相信它是这样工作的。