繁体   English   中英

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

[英]Why does the SqlParameter name/value constructor treat 0 as null?

我在一段代码中观察到一个奇怪的问题,即即席 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 时,SqlDbType 是从 Object 的 Microsoft .NET Framework 类型推断出来的。

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

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

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

您只是调用了与您的情况不同的构造函数。

这样做的原因是,C#允许从整数字面的隐式转换0到枚举类型(这只是整数类型的下面),并且这隐式转换导致(string, SqlDbType)构造成为过载的分辨率比更好的匹配为(string, object)构造函数将int转换为object所需的装箱转换。

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

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

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

对于字符串/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的值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM