SqlParameter(string,object)无法处理常量值

时间:2017-11-10 08:47:39

标签: c# sql-server sqlparameter

我有一个函数,我向SQL Server数据库发送两个请求;但是,在第二个请求中,我得到了SqlException,并且缺少参数@mpe。如果我尝试在0的构造函数中设置常量值SqlParameter

    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查询将按预期执行并检索结果。有人可以解释为什么会这样吗?

1 个答案:

答案 0 :(得分:4)

那是因为当你这样做时:

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);