【问题标题】:SqlCommand (Using Statement / Disposing issue)SqlCommand(使用语句/处置问题)
【发布时间】:2012-09-11 23:47:43
【问题描述】:

举个例子……

        Using cn As New SqlConnection(ConnectionString)
            Try
                Dim cmd As SqlCommand = New SqlCommand
                With cmd
                    .Connection = cn
                    .Connection.Open()
                    .CommandText = "dbo.GetCustomerByID"
                    .CommandType = CommandType.StoredProcedure
                    .Parameters.Add("@CustomerID", SqlDbType.Int, 4)
                    .Parameters("@CustomerID").Value = CustomerID
                End With

                da = New SqlDataAdapter(cmd)
                da.Fill(ds, "Customer")
            Catch ex As Exception

            End Try
        End Using

从我今天的研究来看,这听起来好像基本上没问题,但 SqlCommand 并没有被处理掉。

问题 -> 以下哪个示例是处理此问题的最佳方法?

示例 2 - 手动处理

        Using cn As New SqlConnection(ConnectionString)
            Try
                Dim cmd As SqlCommand = New SqlCommand
                With cmd
                    .Connection = cn
                    .Connection.Open()
                    .CommandText = "dbo.GetCustomerByID"
                    .CommandType = CommandType.StoredProcedure
                    .Parameters.Add("@CustomerID", SqlDbType.Int, 4)
                    .Parameters("@CustomerID").Value = CustomerID
                End With

                da = New SqlDataAdapter(cmd)
                cmd.Dispose()
                da.Fill(ds, "Customer")
            Catch ex As Exception

            End Try
        End Using

示例 3 - 使用 Using 语句自动处理

        Using cn As New SqlConnection(ConnectionString)
            Try
                Using cmd As New SqlCommand
                    With cmd
                        .Connection = cn
                        .Connection.Open()
                        .CommandText = "dbo.GetCustomerByID"
                        .CommandType = CommandType.StoredProcedure
                        .Parameters.Add("@CustomerID", SqlDbType.Int, 4)
                        .Parameters("@CustomerID").Value = CustomerID
                    End With

                    da = New SqlDataAdapter(cmd)
                    da.Fill(ds, "Customer")
                End Using
            Catch ex As Exception

            End Try
        End Using

示例 4 - 与示例 3 相同,但 Try/Catch 在 Using 中 - 这有什么不同吗?

        Using cn As New SqlConnection(ConnectionString)
            Using cmd As New SqlCommand
                Try
                    With cmd
                        .Connection = cn
                        .Connection.Open()
                        .CommandText = "dbo.GetCustomerByID"
                        .CommandType = CommandType.StoredProcedure
                        .Parameters.Add("@CustomerID", SqlDbType.Int, 4)
                        .Parameters("@CustomerID").Value = CustomerID
                    End With

                    da = New SqlDataAdapter(cmd)
                    da.Fill(ds, "Customer")
                Catch ex As Exception

                End Try
            End Using
        End Using

示例 5 - 与示例 4 相同,但在 Using 语句中指定了 CommandText 和 cn - 这有什么优势?

        Using cn As New SqlConnection(ConnectionString)
            Using cmd As New SqlCommand("GetCustomerByID", cn)
                Try
                    With cmd
                        .Connection.Open()
                        .CommandType = CommandType.StoredProcedure
                        .Parameters.Add("@CustomerID", SqlDbType.Int, 4)
                        .Parameters("@CustomerID").Value = CustomerID
                    End With

                    da = New SqlDataAdapter(cmd)
                    da.Fill(ds, "Customer")
                Catch ex As Exception

                End Try
            End Using
        End Using

示例 6 - 与示例 5 相同,但连接是在 cn 而不是 cmd 上打开的。如果只执行一个存储过程,是不是用cmd打开连接比较好?

        Using cn As New SqlConnection(ConnectionString)
            cn.Open()

            Using cmd As New SqlCommand("GetCustomerByID", cn)
                Try
                    With cmd
                        .Connection = cn
                        .CommandType = CommandType.StoredProcedure
                        .Parameters.Add("@CustomerID", SqlDbType.Int, 4)
                        .Parameters("@CustomerID").Value = CustomerID
                    End With

                    da = New SqlDataAdapter(cmd)
                    da.Fill(ds, "Customer")
                Catch ex As Exception

                End Try
            End Using
        End Using

【问题讨论】:

  • using 语句更安全,但在大多数情况下不鼓励使用忽略所有异常的 try/catch。因此,如何以及在何处放置 try catch 都取决于您要完成的工作。你有什么问题?
  • 这个问题在我看来更适合 codereview.stackexchange.com
  • 空的 try/catch 只是一个例子,但在这种情况下,它只是为了安全起见。在此过程的外部,我要检查数据集是否包含任何表。如果没有,我会妥善处理。关于这个问题,它在顶部 - 我在问什么是处理 SqlCommand 处置的最佳方法。我个人认为示例 5 是正确的,但想知道其他人的反馈。
  • @Dan-o - 抱歉,我不知道 codereview.stackexchange.com。如果愿意,我可以删除这个问题。
  • 不,这对我们的业务需求来说是一个严肃的问题。今天我们遇到了各种各样的问题,试图找出连接池问题,并恢复到在我们的 SqlConnection 上添加 Using。在这样做时,我想知道是否需要在 SqlCommand 上执行相同的操作。如果您查看我之前的问题,您会发现这些不是“家庭作业”。

标签: vb.net dispose sqlcommand using-statement


【解决方案1】:

DataAdapter.Fill 命令将自行打开和关闭连接,因此您不需要cmd.Connection.Open()。 (参考:http://msdn.microsoft.com/en-us/library/377a8x4t.aspx 中的备注部分。)

Using 用于SqlConnection 具有为您调用.Close 的效果。

一旦变量cmd 超出范围(如果.NET 确定它不再被使用,则更早),它就有资格进行垃圾回收。

在您的示例 2 中,我不确定在 DataAdapter 使用 cmd 之前处理它是否是个好主意。


[来自Should I call Dispose on a SQLCommand object? 中用户“JefBar Software Services”的信息] 在撰写本文时,由于code in its constructor,在SqlCommand 上调用.Dispose 无效:

public SqlCommand() : base() {
    GC.SuppressFinalize(this);
}

【讨论】:

  • 谢谢。我不知道数据适配器,所以会相应地修改。因此,如果该项目可以进行垃圾收集,您是说 Using 语句真的没有必要吗?
  • @cw_dev 我编辑了我的答案以添加一些专门关于处理 SqlCommand 的信息。
猜你喜欢
  • 1970-01-01
  • 2015-01-06
  • 2011-02-04
  • 2014-06-04
  • 2013-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多