问题描述
我在一段代码中观察到一个奇怪的问题,即即席 SQL 查询没有产生预期的输出,即使它的参数与数据源中的记录匹配.我决定在即时窗口中输入以下测试表达式:
I observed a strange problem in a piece of code where an adhoc SQL query was not producing the expected output, even though its parameters matched records in the data source. I decided to enter the following test expression into the immediate window:
new SqlParameter("Test", 0).Value
这给出了 null
的结果,这让我摸不着头脑.似乎 SqlParameter
构造函数将零视为空值.以下代码产生正确的结果:
This gave a result of null
, which leaves me scratching my head. It seems that the SqlParameter
constructor treats zeroes as nulls. The following code produces the correct result:
SqlParameter testParam = new SqlParameter();
testParam.ParameterName = "Test";
testParam.Value = 0;
// subsequent inspection shows that the Value property is still 0
谁能解释这种行为?是不是故意的?如果是这样,那可能是相当危险的......
Can anyone explain this behaviour? Is it somehow intentional? If so, it's potentially rather dangerous...
推荐答案
如 该构造函数的文档:
当您在 value 参数中指定 Object 时,SqlDbType 是从 Object 的 Microsoft .NET Framework 类型推断出来的.
When you specify an Object in the value parameter, the SqlDbType is inferred from the Microsoft .NET Framework type of the Object.
使用 SqlParameter 的这种重载时要小心 构造函数来指定整数参数值.由于此重载采用 Object 类型的值,因此您必须转换当值为零时,Object 类型的整数值,如以下 C# 示例所示.
Use caution when you use this overload of the SqlParameter constructor to specify integer parameter values. Because this overload takes a value of type Object, you must convert the integral value to an Object type when the value is zero, as the following C# example demonstrates.
Parameter = new SqlParameter("@pname", (object)0);
如果您不执行此转换,编译器会假定您正在尝试调用 SqlParameter (string, SqlDbType) 构造函数重载.
If you do not perform this conversion, the compiler assumes that you are trying to call the SqlParameter (string, SqlDbType) constructor overload.
您只是调用了与您的情况不同的构造函数.
You simply were calling a different constructor than you thought in your case.
这样做的原因是 C# 允许从整数文字 0
到枚举类型(它们只是下面的整数类型)的 隐式 转换,而这种隐式转换会导致(string, SqlDbType)
构造函数比将 int
转换为 object
所需的装箱转换更适合重载解析>(string, object) 构造函数.
The reason for this is that C# allows an implicit conversion from the integer literal 0
to enum types (which are just integral types underneath), and this implicit conversion causes the (string, SqlDbType)
constructor to be a better match for overload resolution than the boxing conversion necessary to convert int
to object
for the (string, object)
constructor.
当你传递一个 int
variable 时,这永远不会成为问题,即使那个变量的值是 0
(因为它是不是零文字),或任何其他具有 int
类型的表达式.如果您如上所示将 int
显式转换为 object
也不会发生这种情况,因为只有一个匹配的重载.
This will never be a problem when you pass an int
variable, even if the value of that variable is 0
(because it is not a zero literal), or any other expression that has the type int
. It will also not happen if you explicitly cast the int
to object
as seen above, because then there is only one matching overload.
这篇关于为什么SqlParameter名称/值构造函数将0视为null?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!