在VB.NET中关闭Oracle连接

在VB.NET中关闭Oracle连接,vb.net,oracle,.net-4.0,plsql,Vb.net,Oracle,.net 4.0,Plsql,在我的程序中,我得到了多个点,在这些点上我打开了到Oracle数据库的连接,通过一个存储过程读取了一些行,该存储过程返回一个游标,将它们放入IDataReader,关闭连接,然后继续 现在一切正常,直到关闭连接。我观察了通过TOAD for Oracle打开到数据库的连接,我发现在我说m\u connection.Close和m\u connection.Dispose之后,数据库似乎保持了一个打开的连接 我使用Oracle.DataAccess并在短时间后得到一个错误,即存在到多个连接。我调试

在我的程序中,我得到了多个点,在这些点上我打开了到Oracle数据库的连接,通过一个存储过程读取了一些行,该存储过程返回一个游标,将它们放入IDataReader,关闭连接,然后继续

现在一切正常,直到关闭连接。我观察了通过TOAD for Oracle打开到数据库的连接,我发现在我说
m\u connection.Close
m\u connection.Dispose
之后,数据库似乎保持了一个打开的连接


我使用Oracle.DataAccess并在短时间后得到一个错误,即存在到多个连接。我调试了我的会话,并确保vb执行close()命令,它执行了,但数据库没有。有人知道如何解决这个问题吗?

在.Net中,您需要将数据库连接包装在Try/Catch/Finally块中,并始终关闭Finally部分中的连接。这有一个缩写,叫做
使用
块。这意味着作为一个类的成员保持一个连接(就像你看起来正在做的那样)几乎总是错误的。Net进行了优化,因此最好为每个查询创建一个新的连接和命令对象

datareader有点特殊:如果您从using块中返回datareader,则可以在datareader使用完毕之前关闭连接。在C#中,我通常使用迭代器(yield-return)来解决这个问题。由于VB.Net不支持此构造,我可能会使用
操作(IDataRecord)
,如下所示:

Public Sub MyOracleQuery(ByVal id As Integer, ByVal ProcessRecord As Action(Of IDataRecord))
    Dim sql As String = "SELECT <columns> FROM MyTable WHERE ID= @Id"
    Using cn As New OracleConnection("connection string"), _
          cmd As New OracleCommand(sql, cn)

        cmd.Parameters.Add("@Id", SqlDbTypes.Int).Value = id
        cn.Open()

        Using (rdr As IDataReader = cmd.ExecuteReader())
            While rdr.Read()
                ProcessRecord(rdr)
            End While
        End Using
    End Using
End Sub

请注意,这需要Visual Studio 2010/.Net 4用于多行匿名方法。对于较旧的平台,您需要声明该方法。

在.Net中,您需要将数据库连接包装在Try/Catch/Finally块中,并始终关闭Finally部分中的连接。这有一个缩写,叫做
使用
块。这意味着作为一个类的成员保持一个连接(就像你看起来正在做的那样)几乎总是错误的。Net进行了优化,因此最好为每个查询创建一个新的连接和命令对象

datareader有点特殊:如果您从using块中返回datareader,则可以在datareader使用完毕之前关闭连接。在C#中,我通常使用迭代器(yield-return)来解决这个问题。由于VB.Net不支持此构造,我可能会使用
操作(IDataRecord)
,如下所示:

Public Sub MyOracleQuery(ByVal id As Integer, ByVal ProcessRecord As Action(Of IDataRecord))
    Dim sql As String = "SELECT <columns> FROM MyTable WHERE ID= @Id"
    Using cn As New OracleConnection("connection string"), _
          cmd As New OracleCommand(sql, cn)

        cmd.Parameters.Add("@Id", SqlDbTypes.Int).Value = id
        cn.Open()

        Using (rdr As IDataReader = cmd.ExecuteReader())
            While rdr.Read()
                ProcessRecord(rdr)
            End While
        End Using
    End Using
End Sub

请注意,这需要Visual Studio 2010/.Net 4用于多行匿名方法。对于较旧的平台,您需要声明该方法。

我像您的第一个代码构造一样使用,但正如我所说的,连接保持活动状态,我在我的storedprocedure类的dispose函数中执行了cn.close和cn.dispose()@Husky-如果您的存储过程类具有dispose函数,那么它也必须封装在using块中。is在using块中,这就是为什么我如此困惑,以至于连接无法关闭!请注意,在某些情况下,客户端操作系统或环境将缓存/池一个“已关闭”的数据库连接,以防很快再次需要它:如果不需要,那么它将在稍后自动关闭。我像您的第一个代码构造一样使用,但是正如我所说的,连接保持活动状态,我在我的storedprocedure类的dispose函数中执行了cn.close和cn.dispose()@Husky-如果您的存储过程类具有dispose函数,那么它也必须封装在using块中。is在using块中,这就是为什么我如此困惑,以至于连接无法关闭!请注意,在某些情况下,客户端操作系统或环境将缓存/池一个“已关闭”的数据库连接,以防很快再次需要它:如果不需要,那么它将在稍后自动关闭。你能发布你的连接字符串吗?你能发布你的连接字符串吗?