Search code examples
.netclonesqlcommand

Does SqlCommand.Clone() create a deep copy or shallow copy?


Does SqlCommand.Clone() create a deep copy or shallow copy? Also, is it safe to call Clone() from multiple threads concurrently (create one command that multiple threads can copy, set parameter values, and execute)?


Solution

  • It is not safe to call Clone from multiple threads because the SqlCommand class itself is not a thread safe class. you should lock before cloning..

    However you can look at the SqlCommand.Clone() method using programs like Reflector, here is the actual code:

    public SqlCommand Clone()
    {
        SqlCommand command = new SqlCommand(this);
        Bid.Trace("<sc.SqlCommand.Clone|API> %d#, clone=%d#\n", this.ObjectID, command.ObjectID);
        return command;
    }
    
    internal static void Trace(string fmtPrintfW, int a1, int a2)
    {
        if (((modFlags & ApiGroup.Trace) != ApiGroup.Off) && (modID != NoData))
        {
            NativeMethods.Trace(modID, UIntPtr.Zero, UIntPtr.Zero, fmtPrintfW, a1, a2);
        }
    }
    
    [DllImport("System.Data.dll", EntryPoint="DllBidTraceCW", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Unicode)]
    internal static extern void Trace(IntPtr hID, UIntPtr src, UIntPtr info, string fmtPrintfW, int a1, int a2);
    
    private SqlCommand(SqlCommand from) : this()
    {
        this.CommandText = from.CommandText;
        this.CommandTimeout = from.CommandTimeout;
        this.CommandType = from.CommandType;
        this.Connection = from.Connection;
        this.DesignTimeVisible = from.DesignTimeVisible;
        this.Transaction = from.Transaction;
        this.UpdatedRowSource = from.UpdatedRowSource;
        SqlParameterCollection parameters = this.Parameters;
        foreach (object obj2 in from.Parameters)
        {
            parameters.Add((obj2 is ICloneable) ? (obj2 as ICloneable).Clone() : obj2);
        }
    }
    

    You can see that it create a new instance and add to it all properties of the old one, but it does not deep copy all properties "like Connection for instance" and so it a shallow copy.