防止注入的C#和SQL参数

防止注入的C#和SQL参数,c#,.net,sql,data-access-layer,sqlparameter,C#,.net,Sql,Data Access Layer,Sqlparameter,我想知道(在下面的代码中)如何确保下面传递的参数中的dataID是文本(或varchar或int) public T ExecuteQuery<T>(Func<IDataReader, T> getResult, string query, params IDataParameter[] parameters) { using (SqlConnection conn = new SqlConnection(this.DefaultConnectio

我想知道(在下面的代码中)如何确保下面传递的参数中的dataID是文本(或varchar或int)

public T ExecuteQuery<T>(Func<IDataReader, T> getResult, string query, params IDataParameter[] parameters)
    {
        using (SqlConnection conn = new SqlConnection(this.DefaultConnectionString))
        {
            conn.Open();

            // Declare the parameter in the query string
            using (SqlCommand command = new SqlCommand(query, conn))
            {
                foreach (var parameter in parameters)
                {
                    command.Parameters.Add(parameter);
                }

                command.Prepare();

                using (SqlDataReader dr = command.ExecuteReader())
                {
                    return getResult(dr);
                }
            }
        }
    }

    public string GetMySpecId(string dataId)
    {
        return ExecuteQuery(
            dr =>
            {
                if (dr.Read())
                {
                    return dr[0].ToString();
                }

                return string.Empty;
            },
            "select specId from MyTable where dataId = @dataId",
            new SqlParameter("dataId", dataId));
    }
在顶部的代码中,我如何将两个或多个参数传递到ExecuteQuery?

代码使用的是关键字,因此您似乎应该只编写额外的转义SQL,并将参数一直附加到方法的末尾。下面是一个以代码为基础的示例

该链接提供了更全面的解释,但
params
提供了更全面的解释,这样您就可以在方法签名的末尾拥有数量可变的参数(只要它们是相同的类型)。它将此
params
变量中的所有最终参数放入一个数组中

 return ExecuteQuery(
        dr =>
        {
            if (dr.Read())
            {
                return dr[0].ToString();
            }

            return string.Empty;
        },
        "select specId from MyTable where dataId = @dataId and somethingelse = @else",
        new SqlParameter("dataId", dataId), 
        new SqlParameter("else", elseVar);
代码使用的是关键字,因此您似乎应该只编写额外的转义SQL,并继续将参数附加到方法的末尾。下面是一个以代码为基础的示例

该链接提供了更全面的解释,但
params
提供了更全面的解释,这样您就可以在方法签名的末尾拥有数量可变的参数(只要它们是相同的类型)。它将此
params
变量中的所有最终参数放入一个数组中

 return ExecuteQuery(
        dr =>
        {
            if (dr.Read())
            {
                return dr[0].ToString();
            }

            return string.Empty;
        },
        "select specId from MyTable where dataId = @dataId and somethingelse = @else",
        new SqlParameter("dataId", dataId), 
        new SqlParameter("else", elseVar);

ExecuteQuery
已接受多个参数。它是一个
ParamArray
,这意味着它接受任意数量的参数并将它们转换为一个数组

 return ExecuteQuery(
        dr =>
        {
            if (dr.Read())
            {
                return dr[0].ToString();
            }

            return string.Empty;
        },
        "select specId from MyTable where dataId = @dataId and somethingelse = @else",
        new SqlParameter("dataId", dataId), 
        new SqlParameter("else", elseVar);
例如,如果我有这样一个函数:

public int Sum(params int[] numbersToSum) { ... }
Sum(1, 2, 5, 6, 1)
我可以这样称呼它:

public int Sum(params int[] numbersToSum) { ... }
Sum(1, 2, 5, 6, 1)
在您的情况下,您可以这样称呼它:

ExecuteQuery(
   dr => { //snip }, 
   query,
   new SqlParameter("dataId", dataId),
   new SqlParameter("anotherParm", parm2),
   new SqlParameter("anotherParm", parm3),
   ... );

ExecuteQuery
已接受多个参数。它是一个
ParamArray
,这意味着它接受任意数量的参数并将它们转换为一个数组

 return ExecuteQuery(
        dr =>
        {
            if (dr.Read())
            {
                return dr[0].ToString();
            }

            return string.Empty;
        },
        "select specId from MyTable where dataId = @dataId and somethingelse = @else",
        new SqlParameter("dataId", dataId), 
        new SqlParameter("else", elseVar);
例如,如果我有这样一个函数:

public int Sum(params int[] numbersToSum) { ... }
Sum(1, 2, 5, 6, 1)
我可以这样称呼它:

public int Sum(params int[] numbersToSum) { ... }
Sum(1, 2, 5, 6, 1)
在您的情况下,您可以这样称呼它:

ExecuteQuery(
   dr => { //snip }, 
   query,
   new SqlParameter("dataId", dataId),
   new SqlParameter("anotherParm", parm2),
   new SqlParameter("anotherParm", parm3),
   ... );

如何使类型也被传递,比如SqlDBType.NVarchar?假设您使用的是
System.Data.SqlClient
中的
SqlParameter
类,那么您可以在正在传递的
SqlParameter
对象上设置它(属性
SqlDBType
)。但是,
SqlDBType
是从构造函数中给定的.NET对象推断出来的,因此您不需要指定它:如何使它也像SqlDBType.NVarchar一样传递类型?假设您在
System.Data.SqlClient
中使用
SqlParameter
类,这是您可以在传递的
SqlParameter
对象上设置的内容(属性
SqlDBType
)。但是,
SqlDBType
是从构造函数中给定的.NET对象推断出来的,因此您不需要指定它:它们是什么类型的?我还想传递不同的类型,也许我应该将其更改为字典?它们是什么类型的?我还想传递不同的类型,也许我应该把它改成字典?