VB.NET:嵌套“使用”数据库访问

问题描述:

我想知道是否这是一个很好的方式做数据访问,在所有的数据库对象被正确关闭和处置?例如:VB.NET:嵌套“使用”数据库访问

Using conn As New SqlConnection(MyConnectionString) 
    Using cmd As New SqlCommand("some SQL here", conn) 
    ... add parameters ... 
    conn.Open() 
    Using dr As SqlDataReader = cmd.ExecuteReader() 
     While dr.Read() 
     ... do stuff ... 
     Wend 
    End Using 
    End Using 
End Using 

嵌套Using像可接受的实践?如果我在Read()循环中的某个点退出方法,那么像这样使用Using将确保所有对象都被正确清理,无论如何,

Using保证在隐含的try/finally块中有序地处置。

' THE FOLLOWING TRY CONSTRUCTION IS EQUIVALENT TO THE USING BLOCK 
Dim resource As New resourceType 
Try 
    ' Insert code to work with resource. 
Catch ex As Exception 
    ' Insert code to process exception. 
Finally 
    ' Insert code to do additional processing before disposing of resource. 
    resource.Dispose() 
End Try 

嵌套使用以类似的方式工作。如果您退出一段代码,它将执行finally块,并正确处理您的对象。

http://msdn.microsoft.com/en-US/library/htd05whh(v=VS.80).aspx

+0

我从来不知道使用语句本质上是一个尝试/最后。我总是用try/catch/finally来处理我的连接。 +1为有用的提示。 – Tony318

+0

听起来不错..如果我在任何时候明确地退出该方法,它仍然适用吗?例如。如果我的SQL是一个'COUNT(*)FROM ...',我使用语句'Return cmd.ExecuteScalar()'。它会在'End Using's之前退出该方法,但是它仍然会清理吗? –

+1

是的,它应该按照正确的顺序触发所有的'finally'块。 –

是的,这没关系。 IDisposable对象的Dispose方法始终被调用。

PS:在这种情况下,Dispose方法也包含Close方法。

要添加,Using块将“幕后”添加一个尝试最后陈述。在finally语句中,它将调用IDisposable.Dispose对象。换句话说,无论你做什么或发生了什么,对象都会被丢弃。

你正在写VB.Net,所以这只是部分适用的,但对于那些使用StyleCop的C#人来说,多重using statements这样会引起异常2202 in StyleCop

msdn链接上存在冗长的部分,关于此规则在stylecop中的用处有不同意见。

我不会判断你是否应该在你的VB.Net代码中注意C#的StyleCops警告。

+0

谢谢..嵌套使用的不明智,或者只是StyleCop的一个怪癖? –

+0

@ ingredient_15939我猜这个规则主要针对第三方[IDisposable](http://msdn.microsoft.com/en-us/library/system.idisposable.aspx)实现。对于MS代码,如[SqlConnections](http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.aspx),假设它遵循正确的处置技术/模式,我们是非常安全的,所以在IDisposable对象是框架对象的情况下,您可能没有多个使用语句。 –