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

我在一段代码中发现了一个奇怪的问题,即即使其参数与数据源中的记录匹配,adhoc 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参数中指定Object时,将从Object的Microsoft .NET Framework类型推断出SqlDbType。

使用SqlParameter构造函数的此重载指定整数参数值时请小心。 因为此重载采用Object类型的值,所以必须在值为零时将整数值转换为Object类型,如下面的C#示例所示。

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

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

你只是调用了一个不同于你案例的构造函数。

原因是C#允许从整数文字0到枚举类型(下面只是整数类型)的隐式转换,并且这种隐式转换使(string, SqlDbType)构造函数更好地匹配重载(string, SqlDbType) ,而不是必须将int转换为object(string, object)构造函数。

传递int 变量时 ,即使该变量的值为0 (因为它不是零文字),或者任何其他类型为int表达式,这也不会成为问题。 如果你如上所示显式地将intobject也不会发生,因为那时只有一个匹配的重载。

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

以下方式您可以完成以下任务:

对于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的值。