【问题标题】:Copy parameters from DbCommand to another DbCommand将参数从 DbCommand 复制到另一个 DbCommand
【发布时间】:2011-01-24 04:53:39
【问题描述】:

如何将DbCommand 参数复制到另一个DbCommand,我想要一个新的DbCommand,其参数与我上一个DbCommand 的参数相同。但现在使用不同的 sql 字符串。

【问题讨论】:

    标签: c# .net enterprise-library dbcommand input-parameters


    【解决方案1】:
    // Copy parameters from cmd1 to cmd2
    // Creates an array with new parameters
    var nsp = cmd1.Parameters.Cast<ICloneable>().Select(x => x.Clone() as SqlParameter).Where(x => x != null).ToArray();
    // Copy parameters into another command
    cmd2.Parameters.AddRange(nsp);
    

    【讨论】:

      【解决方案2】:

      可以将需要重用的代码放在单独的方法中:

      public DbCommand RecycledParameters(string sql, IList<DbParameter> parameters)
      {
          var result = db.GetSqlStringCommand(sql);
          foreach(DbParameter p in parameters)
          {  
              db.AddInParameter(result, p.ParameterName, p.DbType, p.Value);
          }
          return result;
      }
      

      【讨论】:

      • 还有其他方法吗。如果我这样做,我将不得不为我拥有的每个回收参数创建一个函数。
      • 如何创建一个新的 DBCommand 实例?方法原型应该是 public DBCommand AddParameters(DBCommand dbCommand, DBParameterCollection parameters);现在,调用者可以将派生自 DBCommand 的任何类型传递给第一个参数和派生自 DBParameterCollection 的第二个参数类型。例如:AddParams(sqlCommand, sqlParameterCollection)
      • 没错,那会更通用。谢谢。
      【解决方案3】:

      你能做这样的事情吗?

        System.Data.Common.DbCommand command = new System.Data.SqlClient.SqlCommand();
        System.Data.Common.DbCommand command1 = new System.Data.SqlClient.SqlCommand();
      
        command1.Parameters.AddRange(command.Parameters.Cast<System.Data.Common.DbParameter>().ToArray());
      

      【讨论】:

      • 这不起作用,因为您不能将参数从一个命令添加到另一个命令,Add 会识别它并抛出ArgumentExceptionmsdn.microsoft.com/en-us/library/ht4eset1(v=vs.110).aspx Cast+ToArray 将更改集合而不是参数,它们仍然是相同的实例。
      • 这将产生异常:SqlParameter 已被另一个 SqlParameterCollection 包含。
      【解决方案4】:

      如果您所追求的只是 parms 集合,您可以尝试一种帮助方法,该方法在您的命令上创建 .parameters 集合的深层副本。看看这是否会吐出你要找的东西。

      我不能把 ObjectCopier 方法归功于我,它只是我从过去的项目中得到的一个有用的基类方法。

          private DbParameterCollection cloneParms(DbCommand commandWithParms)
          {
              return ObjectCopier.Clone<DbParameterCollection>(commandWithParms.Parameters);
          }
      
          public static class ObjectCopier
          {
              /// <summary>
              /// Perform a deep Copy of the object.
              /// </summary>
              /// <typeparam name="T">The type of object being copied.</typeparam>
              /// <param name="source">The object instance to copy.</param>
              /// <returns>The copied object.</returns>
              public static T Clone<T>(T source)
              {
                  if (!typeof(T).IsSerializable)
                  {
                      throw new ArgumentException("The type must be serializable.", "source");
                  }
      
                  // Don't serialize a null object, simply return the default for that object
                  if (Object.ReferenceEquals(source, null))
                  {
                      return default(T);
                  }
      
                  IFormatter formatter = new BinaryFormatter();
                  Stream stream = new MemoryStream();
                  using (stream)
                  {
                      formatter.Serialize(stream, source);
                      stream.Seek(0, SeekOrigin.Begin);
                      return (T)formatter.Deserialize(stream);
                  }
              }
          }   
      

      【讨论】:

        【解决方案5】:

        vb.net中的一个简单方法

        p 是传入的 sql 参数:

        Dim p1 As SqlClient.SqlParameter = CType(CType(p, ICloneable).Clone, SqlClient.SqlParameter)
        

        【讨论】:

          【解决方案6】:
          private List<Tuple<string, SqlDbType, string>> where_param;
          public IEnumerable<SqlParameter> RecycledParameters(){
            foreach(Tuple<string, SqlDbType, string> tuple in where_param) {
              SqlParameter local_arg = new SqlParameter(tuple.Item1, tuple.Item2);
              local_arg.Value = tuple.Item3;
              yield return local_arg;
            }
          }
          

          【讨论】:

          • 只是添加我对这个问题的回答。
          猜你喜欢
          • 2014-06-19
          • 2011-01-21
          • 1970-01-01
          • 1970-01-01
          • 2021-10-26
          • 2014-08-09
          • 1970-01-01
          • 1970-01-01
          • 2011-11-06
          相关资源
          最近更新 更多