SqlParameter(string, object) 无法处理常量值
SqlParameter(string, object) can't handle constant value
我得到了一个函数,可以向 SQL 服务器数据库发送两个请求;然而,在第二个请求中,我得到一个 SqlException
并且缺少参数 @mpe
。如果我尝试在 SqlParameter
.
的构造函数中设置常量值 0
protected static string GetX(int mpe, string xsection, string xkey)
{
var xSetup = App.Current.Db.GetType<Data.CachedTypes.XSetup>(
"where mpehotel=@mpe and xsection=@xsection and xkey=@xkey",
new System.Data.SqlClient.SqlParameter("@mpe", mpe),
new System.Data.SqlClient.SqlParameter("@xsection", xsection),
new System.Data.SqlClient.SqlParameter("@xkey", xkey));
if (mpe > 0 && xSetup == null)
{
// Fallback mechanism. Always tries to get the default for all MPEs.
xSetup = App.Current.Db.GetType<Data.CachedTypes.XSetup>(
"where mpehotel=@mpe and xsection=@xsection and xkey=@xkey",
new System.Data.SqlClient.SqlParameter("@mpe", 0), <-- THIS FAILES!!
new System.Data.SqlClient.SqlParameter("@xsection", xsection),
new System.Data.SqlClient.SqlParameter("@xkey", xkey));
但是,如果我将常量值 0
提取为局部值 int xmpe = 0
并将其传递给构造函数,SQL 查询将按预期执行并检索结果。有人可以解释为什么会这样吗?
那是因为当你这样做时:
new System.Data.SqlClient.SqlParameter("@mpe", 0)
使用了以下构造函数:
public SqlParameter(string parameterName, SqlDbType dbType)
相当于:
new System.Data.SqlClient.SqlParameter("@mpe", SqlDbType.BigInt);
这是因为 0 可以隐式转换为任何枚举类型,所以此重载优于此重载:
public SqlParameter(string parameterName, object value)
但是当你这样做时
int someInt = 0; // or anything else
new System.Data.SqlClient.SqlParameter("@mpe", someInt)
任意 int 不能隐式转换为枚举(只有常量 0 是),因此选择了正确的重载(使用 object value
)。任意 int 也可以为 0 的事实无关紧要,因为重载决议是在编译时执行的。但是,如果您这样做:
const int mpe = 0;
new System.Data.SqlClient.SqlParameter("@mpe", mpe);
然后又选择了错误的构造函数,因为 mpe
在编译时已知为 0。如果你这样做:
const int mpe = 1;
new System.Data.SqlClient.SqlParameter("@mpe", mpe);
然后再次选择 object value
,原因如上。
要始终强制正确的过载,请将您的 0 转换为对象:
new System.Data.SqlClient.SqlParameter("@mpe", (object) 0);
我得到了一个函数,可以向 SQL 服务器数据库发送两个请求;然而,在第二个请求中,我得到一个 SqlException
并且缺少参数 @mpe
。如果我尝试在 SqlParameter
.
0
protected static string GetX(int mpe, string xsection, string xkey)
{
var xSetup = App.Current.Db.GetType<Data.CachedTypes.XSetup>(
"where mpehotel=@mpe and xsection=@xsection and xkey=@xkey",
new System.Data.SqlClient.SqlParameter("@mpe", mpe),
new System.Data.SqlClient.SqlParameter("@xsection", xsection),
new System.Data.SqlClient.SqlParameter("@xkey", xkey));
if (mpe > 0 && xSetup == null)
{
// Fallback mechanism. Always tries to get the default for all MPEs.
xSetup = App.Current.Db.GetType<Data.CachedTypes.XSetup>(
"where mpehotel=@mpe and xsection=@xsection and xkey=@xkey",
new System.Data.SqlClient.SqlParameter("@mpe", 0), <-- THIS FAILES!!
new System.Data.SqlClient.SqlParameter("@xsection", xsection),
new System.Data.SqlClient.SqlParameter("@xkey", xkey));
但是,如果我将常量值 0
提取为局部值 int xmpe = 0
并将其传递给构造函数,SQL 查询将按预期执行并检索结果。有人可以解释为什么会这样吗?
那是因为当你这样做时:
new System.Data.SqlClient.SqlParameter("@mpe", 0)
使用了以下构造函数:
public SqlParameter(string parameterName, SqlDbType dbType)
相当于:
new System.Data.SqlClient.SqlParameter("@mpe", SqlDbType.BigInt);
这是因为 0 可以隐式转换为任何枚举类型,所以此重载优于此重载:
public SqlParameter(string parameterName, object value)
但是当你这样做时
int someInt = 0; // or anything else
new System.Data.SqlClient.SqlParameter("@mpe", someInt)
任意 int 不能隐式转换为枚举(只有常量 0 是),因此选择了正确的重载(使用 object value
)。任意 int 也可以为 0 的事实无关紧要,因为重载决议是在编译时执行的。但是,如果您这样做:
const int mpe = 0;
new System.Data.SqlClient.SqlParameter("@mpe", mpe);
然后又选择了错误的构造函数,因为 mpe
在编译时已知为 0。如果你这样做:
const int mpe = 1;
new System.Data.SqlClient.SqlParameter("@mpe", mpe);
然后再次选择 object value
,原因如上。
要始终强制正确的过载,请将您的 0 转换为对象:
new System.Data.SqlClient.SqlParameter("@mpe", (object) 0);