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

Bra*_*ith 25 c# sql-server ado.net sqlparameter

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

new SqlParameter("Test", 0).Value
Run Code Online (Sandbox Code Playgroud)

这给了null我一个让我挠头的结果.似乎SqlParameter构造函数将零视为空值.以下代码生成正确的结果:

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

谁能解释这种行为?这是故意的吗?如果是这样,它可能相当危险......

Joe*_*oey 30

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

在value参数中指定Object时,将从Object的Microsoft .NET Framework类型推断出SqlDbType.

使用SqlParameter构造函数的此重载指定整数参数值时请小心.由于这种重载采用类型的值对象,则必须将整数值转换为对象的类型,如果值是零,如下面的C#示例演示.

Parameter = new SqlParameter("@pname", (object)0);
Run Code Online (Sandbox Code Playgroud)

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

你只是调用了一个不同于你的情况的构造函数.

这样做的原因是,C#允许隐式的从整数字面转换0到枚举类型(这只是整型下),这隐式转换导致的(string, SqlDbType)构造函数是重载超过必要的装箱转换来转换一个更好的匹配int,以object对于(string, object)构造函数.

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


Eli*_*ain 6

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

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

对于string/varchar类型的数据:

SqlParameter pVarchar = new SqlParameter
                    {
                        ParameterName = "Test",
                        SqlDbType = System.Data.SqlDbType.VarChar,
                        Value = string.Empty,
                    };
Run Code Online (Sandbox Code Playgroud)

对于int类型数据:

SqlParameter pInt = new SqlParameter
                    {
                        ParameterName = "Test",
                        SqlDbType = System.Data.SqlDbType.Int,
                        Value = 0,
                    };
Run Code Online (Sandbox Code Playgroud)

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

  • @Joey,是的,你是对的,谢谢你的时间. (2认同)