Copy parameters from DbCommand to another DbCommand
Asked Answered
W

6

9

How do you copy DbCommand parameters to another DbCommand, I want a new DbCommand with the same parameters as my last DbCommand. But now with a different sql string.

Witchhunt answered 24/1, 2011 at 4:53 Comment(0)
V
3

You could put the code you need to re-use in a separate method:

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;
}
Vinitavinn answered 24/1, 2011 at 5:3 Comment(3)
is there any other way. If I would do this I would have to create a function for every recycled parameters I have.Witchhunt
how are able to create a new instance of DBCommand? The method prototype should have been public DBCommand AddParameters(DBCommand dbCommand, DBParameterCollection parameters); now the caller could pass any type that derives from DBCommand for the first param and for the second param type that derives from DBParameterCollection. ex: AddParams(sqlCommand, sqlParameterCollection)Ineffaceable
True, that would be more generic. Thanks.Vinitavinn
A
4
// 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);
Affray answered 6/11, 2014 at 14:35 Comment(0)
V
3

You could put the code you need to re-use in a separate method:

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;
}
Vinitavinn answered 24/1, 2011 at 5:3 Comment(3)
is there any other way. If I would do this I would have to create a function for every recycled parameters I have.Witchhunt
how are able to create a new instance of DBCommand? The method prototype should have been public DBCommand AddParameters(DBCommand dbCommand, DBParameterCollection parameters); now the caller could pass any type that derives from DBCommand for the first param and for the second param type that derives from DBParameterCollection. ex: AddParams(sqlCommand, sqlParameterCollection)Ineffaceable
True, that would be more generic. Thanks.Vinitavinn
L
2

could you do something like this?

  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());
Landsman answered 24/1, 2011 at 6:26 Comment(2)
This won't work because you can't add parameters from one command to another, Add will recognize it and throw an ArgumentException. msdn.microsoft.com/en-us/library/ht4eset1(v=vs.110).aspx The Cast+ToArray will change the collection not the parameters, they are still the same instances.Sustentacular
This will produce exception: The SqlParameter is already contained by another SqlParameterCollection.Shields
G
1

If all you are after is the parms collection, you could try a helper method that creates a deep copy of the .parameters collection on your command. See if this will spit out what your looking for.

I can't take credit for the ObjectCopier method, it's just a useful base class method I got from a past project.

    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);
            }
        }
    }   
Glance answered 24/1, 2011 at 5:30 Comment(0)
S
0

A simple way in vb.net

p is an incoming sqlparameter:

Dim p1 As SqlClient.SqlParameter = CType(CType(p, ICloneable).Clone, SqlClient.SqlParameter)
Straley answered 17/7, 2018 at 17:41 Comment(0)
I
0
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;
  }
}
Ivanaivanah answered 5/1, 2021 at 19:26 Comment(1)
just adding my answer to the question I was having about this.Ivanaivanah

© 2022 - 2024 — McMap. All rights reserved.