添加IDbCommand参数

本文关键字:参数 IDbCommand 添加 | 更新日期: 2023-09-27 18:15:23

我正在创建一个小的辅助函数来返回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;
    }

当这段代码执行时,我收到一个InvalidCastException,它声明如下:

SqlParameterCollection只接受非空的SqlParameter类型对象,不接受String对象。

代码落在行上:

cmd.Parameters.Add(Parameters.GetValue(i));

任何想法?

对以上代码的任何改进都是值得赞赏的。


实际解决方案:

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

谢谢你的想法/链接等:)

添加IDbCommand参数

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

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

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

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

我知道这不是你想要的,但我有一个更简单、更可靠的解决方案。

Microsoft Patterns and Practices库包含一个数据访问应用程序块,它非常强大且易于使用。下面是实际代码中执行存储过程并返回数据集的示例:

 object[] ParameterValues = new object[] {"1",DateTime.Now, 12, "Completed", txtNotes.Text};
 Database db = DatabaseFactory.CreateDatabase("ConnectionStringName");
 DataSet ds =  = db.ExecuteDataSet("StoredProcName", ParameterValues);

如果连接是OleDb, ODBC等并不重要。第一行代码中的ConnectionStringName只是.config文件中定义的Consternating的名称。传入一个Connection String名称、存储的过程名称和一个对象数组,它们构成了参数。这只是众多功能中的一个。

你会得到你想要建立的一切,甚至更多。

官方网站在这里:http://msdn.microsoft.com/en-us/library/ff648951.aspx

为了节省您的搜索时间,可以在这里找到Data类文档:http://msdn.microsoft.com/en-us/library/microsoft.practices.enterpriselibrary.data(PandP.50).aspx

(微软免费,定期更新)

这个答案的目的比你正在做的稍微具体一些,但是在@Dismissile的回答的基础上,我使用Dictionary在我的个人项目中为foreach循环提供参数名称和值。

using( IDbCommand dbCommand = dbConnection.CreateCommand() )
{
    dbCommand.CommandText = Properties.Settings.Default.UpdateCommand;
    Dictionary<string,object> values = new Dictionary<string,object>()
    {
        {"@param1",this.Property1},
        {"@param2",this.Property2},
        // ...
    };
    foreach( var item in values )
    {
        var p = dbCommand.CreateParameter();
        p.ParameterName = item.Key;
        p.Value = item.Value;
        dbCommand.Parameters.Add(p);
    }
}

您的Parameters参数需要为IDataParameter[]类型,并且根据错误文本,具体实现需要为SqlParameter[]类型。

如果您希望保留签名,则需要一个工厂来派生必要的具体实现。

添加using System.Data.SqlClient;cmd.Parameters.Add(new SqlParameter("@parameterName", value));