将参数添加到IDbCommand

Stu*_*ler 46 c# datatable

我正在创建一个小辅助函数来返回一个DataTable.我想跨所有供应商合作ADO.Net支持,所以我想到了使一切使用IDbCommandDbCommand在可能的情况.

我用以下代码达到了绊脚石:

    private static DataTable QueryImpl(ref IDbConnection conn, String SqlToExecute, CommandType CommandType, Array Parameters)
    {
        SetupConnection(ref conn);
        // set the capacity to 20 so the first 20 allocations are quicker...
        DataTable dt = new DataTable();
        using (IDbCommand cmd = conn.CreateCommand())
        {
            cmd.CommandText = SqlToExecute;
            cmd.CommandType = CommandType;
            if (Parameters != null && Parameters.Length > 0)
            {
                for (Int32 i = 0; i < Parameters.Length; i++)
                {
                    cmd.Parameters.Add(Parameters.GetValue(i));
                }
            }
            dt.Load(cmd.ExecuteReader(), LoadOption.OverwriteChanges);
        }
        return dt;
    }
Run Code Online (Sandbox Code Playgroud)

执行此代码时,我会收到InvalidCastException以下内容:

SqlParameterCollection只接受非null的SqlParameter类型对象,而不接受String对象.

代码落在了线上:

cmd.Parameters.Add(Parameters.GetValue(i));
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

对上述代码的任何改进都表示赞赏.


实际解决方案

    private static readonly Regex regParameters = new Regex(@"@\w+", RegexOptions.Compiled);
    private static DataTable QueryImpl(ref DbConnection conn, String SqlToExecute, CommandType CommandType, Object[] Parameters)
    {
        SetupConnection(ref conn);
        DataTable dt = new DataTable();
        using (DbCommand cmd = conn.CreateCommand())
        {
            cmd.CommandText = SqlToExecute;
            cmd.CommandType = CommandType;
            if (Parameters != null && Parameters.Length > 0)
            {
                MatchCollection cmdParams = regParameters.Matches(cmd.CommandText);
                List<String> param = new List<String>();
                foreach (var el in cmdParams)
                {
                    if (!param.Contains(el.ToString()))
                    {
                        param.Add(el.ToString());
                    }
                }
                Int32 i = 0;
                IDbDataParameter dp;
                foreach (String el in param)
                {
                    dp = cmd.CreateParameter();
                    dp.ParameterName = el;
                    dp.Value = Parameters[i++];
                    cmd.Parameters.Add(dp);
                }
            }
            dt.Load(cmd.ExecuteReader(), LoadOption.OverwriteChanges);
        }
        return dt;
    } 
Run Code Online (Sandbox Code Playgroud)

感谢您的想法/链接等:)

Dis*_*ile 83

我相信IDbCommand有一个CreateParameter()方法:

var parameter = command.CreateParameter();
parameter.ParameterName = "@SomeName";
parameter.Value = 1;

command.Parameters.Add(parameter);
Run Code Online (Sandbox Code Playgroud)


one*_*ack 28

您可以将接受的答案的代码添加到扩展方法:

public static class DbCommandExtensionMethods
{
    public static void AddParameter (this IDbCommand command, string name, object value)
    {
        var parameter = command.CreateParameter();
        parameter.ParameterName = name;
        parameter.Value = value;
        command.Parameters.Add(parameter);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 不是直接的.但对于遇到这个问题的每个人来说,这可能会带来一些好处.并且我不允许在帖子中添加评论,所以我必须添加2美分作为答案. (13认同)