2011-07-26 10 views
6

SqlCommand.Clone()ディープコピーまたはシャローコピーを作成しますか?また、Clone()を複数のスレッドから同時に呼び出しても安全です(複数のスレッドがコピーしたり、パラメータ値を設定して実行できるコマンドを1つ作成して実行する)?SqlCommand.Clone()はディープコピーまたはシャローコピーを作成しますか?

+0

クローニング、深いコピーと浅いコピー、および例の詳細については、[Object.MemberwiseClone](http://msdn.microsoft.com/en-us/library/system.object.memberwiseclone.aspx)メソッドを参照してください。 http://stackoverflow.com/questions/699210/why-should-i-implement-icloneable-in-c/4186747#4186747 – Sreekumar

+0

私の質問の理由は、複数のスレッドからのClone()SqlCommandに対してスレッドセーフであるかどうかでした。同時。議論から、それは真実だと思われるので、深いクローンではないが、パラメータセットを複製する。そのため、スタートアップ時にSqlCommandを一度準備し、後で複数のスレッドから並列にクローンを作成して作業を省くことができます。 – yzorg

答えて

2

SqlCommandクラス自体がスレッドセーフなクラスではないため、Cloneを複数のスレッドから呼び出すことは安全ではありません。

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

あなたはそれが新しいインスタンスを作成することを確認し、それに追加することができます:あなたはReflectorなどのプログラムを使用してSqlCommand.Clone()方法を見ることができますしかし

が、ここで実際のコード..ですlockクローニングの前にすべき古いもののすべてのプロパティが、例えば "Connectionのように"すべてのプロパティを深くコピーしないので、浅いコピーです。

+0

私はSqlConnectionのようなcritcalリソースを複製することは期待していません。私はそれが深いコピーで 'ベストテスティング'を実行しているICloneableであるすべてのパラメータをクローンしているので、私は言うでしょう。私はそれが '元の' SqlCommandを使用することはありませんので、接続とトランザクションのプロパティは常に '元の'インスタンスからnullになることを検討しているアプリでは。 – yzorg

+0

@yzorg:そうですが、「SqlConnection」、「Parameters' ..」のようにすべてのデータを深くクローンしないため、浅いコピーと見なされます。すべてのデータを深くコピーすると、「深いコピー」としか考えられませんでした。元のコピーやコピーからプロパティを変更しても、他のコピーは影響を受けません。 –

2

SqlCommand.Cloneメソッドは、シャローコピーを実行します。参照型のプロパティは、両方のSqlCommandインスタンスで同じオブジェクトを表します。したがって、スレッドセーフではありません。

AFAIK .NET FrameworkのClone()(MemberwiseClone)メソッドはすべて浅いコピーです。

コードを投稿していませんが、クローン作成ではなく新しいSqlCommandを作成することをお勧めします。

関連する問題