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

本文关键字:视为 null 构造函数 SqlParameter 名称 为什么 | 更新日期: 2023-09-27 18:16:20

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

new SqlParameter("Test", 0).Value

这给出了null的结果,这让我挠头。似乎SqlParameter构造函数将零视为null。下面的代码产生正确的结果:

SqlParameter testParam = new SqlParameter();
testParam.ParameterName = "Test";
testParam.Value = 0;
// subsequent inspection shows that the Value property is still 0

有人能解释这种行为吗?这是故意的吗?

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

如该构造函数的文档中所述:

当你在value参数中指定一个对象时,SqlDbType是从该对象的microsoft.net Framework类型中推断出来的。

使用SqlParameter构造函数的重载来指定整型参数值时要小心。由于此重载接受Object类型的值,因此必须在值为零时将整型值转换为Object类型,如下面的c#示例所示。

Parameter = new SqlParameter("@pname", (object)0);

如果不执行此转换,编译器假定您正在尝试调用SqlParameter(string, SqlDbType)构造函数重载。

你只是调用了一个与你想象的不同的构造函数。

这样做的原因是c#允许一个隐式转换,从整型文字0到枚举类型(下面只是整型类型),这种隐式转换导致(string, SqlDbType)构造函数比(string, object)构造函数将int转换为object所需的装箱转换更好地匹配重载解析。

当您传递一个int 变量时,即使该变量的值是0(因为它不是一个零字面值)或任何其他类型为int的表达式,也不会出现问题。如果如上所示显式地将int转换为object,也不会发生这种情况,因为只有一个匹配的重载。

在传递/添加参数时使用类型化数据是很好的做法。

完成任务的方法如下:

对于string/varchar类型的数据:

SqlParameter pVarchar = new SqlParameter
                    {
                        ParameterName = "Test",
                        SqlDbType = System.Data.SqlDbType.VarChar,
                        Value = string.Empty,
                    };

对于int类型数据:

SqlParameter pInt = new SqlParameter
                    {
                        ParameterName = "Test",
                        SqlDbType = System.Data.SqlDbType.Int,
                        Value = 0,
                    };

您可以根据您使用的数据更改SqlDbType的值