Создает ли SqlCommand.Clone () глубокую или мелкую копию? - PullRequest
7 голосов
/ 26 июля 2011

Создает ли SqlCommand.Clone() глубокую или мелкую копию? Также безопасно ли одновременно вызывать Clone() из нескольких потоков (создать одну команду, которую могут копировать несколько потоков, установить значения параметров и выполнить)?

Ответы [ 2 ]

3 голосов
/ 26 июля 2011

Не безопасно вызывать Clone из нескольких потоков, потому что сам класс SqlCommand не является потокобезопасным классом. Вы должны lock перед клонированием ..

Однако вы можете посмотреть на метод SqlCommand.Clone(), используя такие программы, как Reflector, вот фактический код:

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

Вы можете видеть, что он создает новый экземпляр и добавляет к нему все свойства старого, но он не копирует все свойства "как, например, Connection например", и поэтому это мелкая копия.

2 голосов
/ 26 июля 2011

Метод SqlCommand.Clone выполняет поверхностное копирование.Любые свойства, являющиеся ссылочным типом, будут представлять один и тот же объект в обоих экземплярах SqlCommand.Таким образом, потокобезопасен.

AFAIK, все методы Clone () (MemberwiseClone) в .NET Framework являются мелкими копиями.

Вы не опубликовали свой код, но я бы предложил создатьновый SqlCommand вместо клонирования.

...