SqlCommand.Clone() 是否创建深复制或浅复制?

发布于 2024-11-26 07:43:21 字数 103 浏览 1 评论 0原文

SqlCommand.Clone() 是否创建深复制或浅复制?另外,从多个线程并发调用 Clone() 是否安全(创建一个多个线程可以复制、设置参数值并执行的命令)?

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)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

扮仙女 2024-12-03 07:43:21

从多个线程调用 Clone 并不安全,因为 SqlCommand 类本身不是线程安全类。在克隆之前你应该lock

但是你可以使用Reflector等程序查看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);
    }
}

您可以看到它创建了一个新实例并向其中添加了旧实例的所有属性,但它不会深度复制所有属性“例如 Connection”,因此它是浅复制。

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.

逆光下的微笑 2024-12-03 07:43:21

SqlCommand.Clone 方法执行浅复制。任何属于引用类型的属性都将表示两个 SqlCommand 实例中的同一对象。所以,不是线程安全的。

AFAIK,.NET 框架中的所有 Clone() (MemberwiseClone) 方法都是浅拷贝。

您尚未发布代码,但我建议创建一个新的 SqlCommand 而不是克隆。

The SqlCommand.Clone method performs a shallow copy. Any properties that are a reference type will represent the same object in both SqlCommand instances. So, not thread safe.

AFAIK, all Clone() (MemberwiseClone) methods in the .NET framework are shallow copies.

You haven't posted your code, but I would suggest creating a new SqlCommand rather than cloning.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文