System.InvalidOperationException:ExecuteReader 需要打开且可用的连接。连接的当前状态为关闭

Posted

技术标签:

【中文标题】System.InvalidOperationException:ExecuteReader 需要打开且可用的连接。连接的当前状态为关闭【英文标题】:System.InvalidOperationException: ExecuteReader requires an open and available connection. The connection's current state is closed 【发布时间】:2016-02-10 07:47:03 【问题描述】:

我在使用不同解决方案的客户服务模块时遇到问题。我认为问题在于我的调用或获取连接的方法

这是我的班级DBConnForAccess

Imports System.Data.OleDb
Imports System.Data.Odbc

Public Class DBConnForAccess

Dim Conn As New OleDbConnection
Dim cmd As New OleDbCommand
Dim Trans As OleDbTransaction

Public Function DBConnect(ByVal filePath As String, pass As String)
    Try
        ' open Database

        'Conn = New SqlConnection("Data Source=" + ServerName + "\" + DBName + ";User ID=" + DBUsername + ";Password=" + DBPassword + ";Initial Catalog= '" + TB + "'")
        Conn = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filePath + ";Jet OLEDB:Database Password=" + pass + ";")
        '                          "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\mydatabase.mdb;Jet OLEDB:Database Password=MyDbPassword;"

        If Conn.State = ConnectionState.Closed Then
            Conn.Open()
        End If

        ' create transaction
        Trans = Conn.BeginTransaction
        Return "Ok"

    Catch ex As Exception
        Return ex.Message
    End Try

End Function

Public Sub ExecuteSQL(ByVal sql As String, ByVal ParamArray Obj() As Object)
    ' command Object
    Dim CMD As New OleDbCommand(sql, Me.Conn, Me.Trans)

    'add the parameters to the sql command
    Dim I As Integer
    For I = 0 To Obj.Length - 1
        CMD.Parameters.AddWithValue("@" & I, Obj(I))
    Next

    'execute the sql
    CMD.ExecuteNonQuery()
End Sub

Public Sub commit()
    Me.Trans.Commit()
    Me.Trans = Me.Conn.BeginTransaction
End Sub

Public Sub rollback()
    Me.Trans.Rollback()
    Me.Trans = Me.Conn.BeginTransaction
End Sub

Public Sub CloseDB()
    Me.Conn.Close()
    Me.Conn.Dispose()
    Me.Trans.Dispose()
End Sub

Public Function ReadData(ByVal sql As String, ByVal ParamArray Obj() As Object)
    ' command Object
    Dim CMD As New OleDbCommand(sql, Me.Conn, Me.Trans)

    'add the parameters to the sql command
    Dim I As Integer
    For I = 0 To Obj.Length - 1
        CMD.Parameters.AddWithValue("@" & I, Obj(I))
    Next

    Dim R = CMD.ExecuteReader()
    'Do While R.Read

    'Loop
    Return R

End Function
End Class

这是我用来获取数据的 Sub:

Dim connection As String = txt_util.readFromTextFile("ConnStr_2.txt", 0) + "Billing.mdb"
 'connection string is in a text file with text at line 0 as "C:\BILLSERV\"

 Private Sub searchAccnt(ByVal SIN As String)
    'clear other fields
    Clear("Acct")
    Try
        AccntDetail.DBConnect("ConcessionairesAccnt")
        'Dim RS = AccntDetail.ReadData("Select * From AllAccounts Where SIN=@0", txtSIN.Text.Trim)
        Dim RS = AccntDetail.ReadData("Select * From viewCSFAccnt Where SIN=@0", SIN)

        RS.Read()
        If RS.Hasrows = 0 Then
            MsgBox("Accounts not found. Check the SIN you Enter.", MsgBoxStyle.Information + MsgBoxStyle.OkOnly, "Records not found.")
            'txtAppNo.Focus()
            Exit Sub
        Else
            'MsgBox("Accounts correct.", MsgBoxStyle.Information + MsgBoxStyle.OkOnly, "Records found.")
            txtZoneNo.Text = RS.Item("Zone").ToString
            txtSeq.Text = RS.Item("SeqNo").ToString
            txtAccntName.Text = RS.Item("AccountName").ToString
            txtAccntAddress.Text = RS.Item("HouseNo").ToString + " " + RS.Item("BLDGName").ToString + " " + RS.Item("Street").ToString + _
                                   " " + RS.Item("BRGY").ToString
            txtMeterNo.Text = RS.Item("MeterNo").ToString
            txtAccntStatus.Text = varA.AccntStatus(RS.Item("Status").ToString)


            'Dim con = AccessAccnt.DBConnect(connection, "")
            'If con <> "Ok" Then
            '    MsgBox("Cannot establish a Connection to the server.", MsgBoxStyle.Critical, "Connection Lost...")
            'End If

            Dim ZoneNo = "Z" + GetChar(txtZoneNo.Text, 1) + GetChar(txtZoneNo.Text, 2) + "B" + GetChar(txtZoneNo.Text, 3) + GetChar(txtZoneNo.Text, 4)
            AccessAccnt.DBConnect(connection, "")
            Dim Acc = AccessAccnt.ReadData("SELECT * FROM " & ZoneNo & " WHERE AcctNo3=@1", txtSeq.Text)
            Acc.Read()
            txtLastReading.Text = Acc.Item("LastReading").ToString
            Acc.close()
            AccessAccnt.CloseDB()

        End If
        RS.Dispose()
        AccntDetail.CloseDB()

        dbCounter.DBConnect("ConcessionairesAccnt")
        Dim result = dbCounter.ReadData("Select Top 1 CSFNo From CSFMaster WHERE (CSFNo LIKE '%" & ctrDate() & "%') order by CSFNo Desc")
        result.read()
        If result.hasrows = 0 Then
            txtTrackingNo.Text = ctrDate() & "-" & "000001"
        Else
            txtTrackingNo.Text = counter.CtrLastItemWithChar("ConcessionairesAccnt", "CSFNo", "CSFMaster", "WHERE (CSFNo LIKE '%" & ctrDate() & "%') ORDER BY CSFNo DESC", 5)
        End If
        dbCounter.CloseDB()

    Catch ex As Exception
        MsgBox(ex.ToString)
    End Try

End Sub

错误在这里抛出:

Dim Acc = AccessAccnt.ReadData("SELECT * FROM " & ZoneNo & " WHERE AcctNo3=@1", txtSeq.Text)

它说:

System.InvalidOperationException: ExecuteReader requires an open and available connection. The connection's current state is closed.

Sub 的其他部分工作正常,我在 MSSQL Server 数据库上获取数据的部分。问题在于访问数据获取代码。

我尝试在另一个项目上使用代码(只是我获取访问数据的代码)我在其他解决方案上工作。但是我将我的代码复制并粘贴到此解决方案中的任何表单上,我一直给出错误。

我想也许我在某个地方关闭了连接,但这是我在整个项目中使用此代码的唯一实例。 (只是为了获取最后的阅读记录。)

数据库位于正确的位置 (C:\BILLSERV)

我试过在 SE 上搜索它,但我只能看到关于可能忘记打开连接的建议。我之前使用过这段代码,这段代码适用于我的其他解决方案。我似乎无法让它在这个特定的项目上工作。我想知道为什么..

我尝试使用此代码运行另一个项目,它运行良好。

VB.net 2012 上是否存在有关 Access 连接的错误,我已经使用此代码(DBConnForAccess 类)大约一年了,这是我第一次遇到此错误。顺便说一句,我使用 Access 2003,因为这个数据库曾经是用于在 VB6 中创建的旧系统。

最后这可能是因为解决方案来自另一台使用与我相同的 VB.Net 程序的计算机。因为我们在这里作为一个团队工作。希望对这些系统有更好了解的人可以提供帮助。提前致谢。

编辑

如果已建立连接,应该会出现一个可访问的 .ldb 文件。 (我在另一个项目上对此进行了测试,一旦建立连接,就会出现一个 ldb 文件,因为我们都知道 ldb 文件包含使用 db 文件的用户的数据。)我试图重新运行系统,而我正在使用系统没有创建 ldb 文件。

另外,我想也许我在某个地方关闭了连接,但 这是我在 access 中打开连接的唯一实例,并且我在整个项目中使用了代码。 (只是为了获取最后的阅读记录。)

所以这不是与“There is already an open DataReader…” Reuse or Dispose DB Connections? 重复,只是为了澄清

【问题讨论】:

如果您的 DBConnect 失败并返回错误消息怎么办?你知道会发生什么吗?如果您不使用异常,请不要捕获它们。 @Steve 我应该使用什么?我用这条线检查我的数据库是否连接 If con "Ok" Then 。它总是返回“无法建立与服务器的连接。” 可能是什么问题?我尝试了其他方法,更改目标框架,下载 AccessDatabaseEngine 并安装它。还是没有运气 好吧,开始第一次调用 DBConnect 似乎没有为访问数据库传递有效的文件名(缺少扩展名),然后第二次连接使用了一个我们看不到的变量它是如何初始化的,或者它是否被初始化。如果你有调试器,是时候开始使用它了。 @Steve 抱歉,我已经添加了我在连接字符串中使用的行。它在一个文本文件中。被另一个类读取一个 textfileUtility。 您需要开启 Option Strict。 DBConnForAccess 看起来正在接近 inner platform 反模式。时间和代码似乎最好用实际类型来实现 SQL 参数,而不是所有 ObjectUsing 块来关闭和处理应该关闭和处理的东西 【参考方案1】:

经过一周的调试和阅读网络文章。 我们找到了错误的罪魁祸首。

Advance compiler Settings中的Target CPU Option好像改成了AnuCPU

我们在检查了我们使用的其他应用程序项目后注意到了这一点。

改回 x86 解决了连接问题。

我想知道为什么这会影响到访问的连接。

现在一切正常。感谢 Plutonix 和 Steve 提出的所有建议,我们将对代码进行更改。

【讨论】:

以上是关于System.InvalidOperationException:ExecuteReader 需要打开且可用的连接。连接的当前状态为关闭的主要内容,如果未能解决你的问题,请参考以下文章

视图中出现 InvalidOperationException.Collection 被修改错误