VB Error: "There is a already a datareader associated with this command"

VB Error: "There is a already a datareader associated with this command"

尝试运行 ServiceStack 服务时,出现以下错误:

调试时,代码只 运行 一次,没有循环两次,我还在所有其他带有数据读取器的函数上设置了断点,其中 none 个函数首先被命中,因此设法将问题缩小到这个功能。

Public Function GetVisitList(SiteKey As String) As List(Of VisitDetail) Implements IVisitorData.GetVisitList
        Dim vlcmd As SqlClient.SqlCommand = New SqlCommand
        vlcmd.CommandTimeout = 60

        Try
            vlcmd.Connection = Conn
            vlcmd.CommandType = CommandType.StoredProcedure
            vlcmd.CommandText = "GetVisitList"

            vlcmd.Parameters.AddWithValue("@sitekey", SiteKey)

            Dim dr As SqlDataReader = vlcmd.ExecuteReader()

            Dim visitList As New List(Of VisitDetail)

            While dr.Read()
                Dim visit As New VisitDetail

                If Not IsDBNull(dr("VKey")) Then
                    visit.VisitorKey = dr("VKey")
                End If

                If Not IsDBNull(dr("VisitIP")) Then
                    visit.IP = dr("VisitIP")
                End If

                If Not IsDBNull(dr("SiteKey")) Then
                    visit.SiteKey = dr("SiteKey")
                End If

                If Not IsDBNull(dr("Alert")) Then
                    visit.AlertDescription = dr("Alert")
                End If

                If Not IsDBNull(dr("AlertNo")) Then
                    visit.AlertNumber = dr("AlertNo")
                End If

                If Not IsDBNull(dr("VisitNo")) Then
                    visit.VisitNumber = dr("VisitNo")
                Else
                    visit.VisitNumber = 0
                End If

                If Not IsDBNull(dr("Invited")) Then
                    visit.Invited = dr("Invited")
                End If

                If Not IsDBNull(dr("Chatted")) Then
                    visit.Chatted = dr("Chatted")
                End If

                If Not IsDBNull(dr("Prospect")) Then
                    visit.Prospect = dr("Prospect")
                End If

                If Not IsDBNull(dr("Customer")) Then
                    visit.Customer = dr("Customer")
                End If

                If Not IsDBNull(dr("HackRaised")) Then
                    visit.Hacker = dr("HackRaised")
                End If

                If Not IsDBNull(dr("Spider")) Then
                    visit.Spider = dr("Spider")
                End If

                If Not IsDBNull(dr("Cost")) Then
                    visit.ThisVisitCost = dr("Cost")
                End If

                If Not IsDBNull(dr("Revenue")) Then
                    visit.ThisVisitRevenue = dr("Revenue")
                End If

                If Not IsDBNull(dr("Visits")) Then
                    visit.Visits = dr("Visits")
                Else
                    visit.Visits = 0
                End If

                If Not IsDBNull(dr("FirstDate")) Then
                    visit.FirstVisitDate = dr("FirstDate")
                End If

                If Not IsDBNull(dr("TotalCost")) Then
                    visit.TotalCost = dr("TotalCost")
                End If

                If Not IsDBNull(dr("TotalRevenue")) Then
                    visit.TotalRevenue = dr("TotalRevenue")
                End If

                If Not IsDBNull(dr("OperatingSystem")) Then
                    visit.OperatingSystem = dr("OperatingSystem")
                End If

                If Not IsDBNull(dr("Browser")) Then
                    visit.Browser = dr("Browser")
                End If

                If Not IsDBNull(dr("SearchEngine")) Then
                    visit.SearchEngine = dr("SearchEngine")
                End If

                If Not IsDBNull(dr("Referrer")) Then
                    visit.Referrer = dr("Referrer")
                End If

                If Not IsDBNull(dr("Keywords")) Then
                    visit.Keywords = dr("Keywords")
                End If

                If Not IsDBNull(dr("ReferrerQuery")) Then
                    visit.ReferrerQuery = dr("ReferrerQuery")
                End If

                If Not IsDBNull(dr("Name")) Then
                    visit.ContactName = dr("Name")
                End If

                If Not IsDBNull(dr("Email")) Then
                    visit.ContactEmail = dr("Email")
                End If

                If Not IsDBNull(dr("Company")) Then
                    visit.ContactCompany = dr("Company")
                End If

                If Not IsDBNull(dr("Telephone")) Then
                    visit.ContactTelephone = dr("Telephone")
                End If

                If Not IsDBNull(dr("Fax")) Then
                    visit.ContactFax = dr("Fax")
                End If

                If Not IsDBNull(dr("Street")) Then
                    visit.ContactStreet = dr("Street")
                End If

                If Not IsDBNull(dr("City")) Then
                    visit.ContactCity = dr("City")
                    visit.City = dr("City")
                End If

                If Not IsDBNull(dr("Zip")) Then
                    visit.ContactZip = dr("Zip")
                End If

                If Not IsDBNull(dr("Country")) Then
                    visit.ContactCountry = dr("Country")
                    visit.Country = dr("Country")
                End If

                If Not IsDBNull(dr("Web")) Then
                    visit.ContactWebSite = dr("Web")
                End If

                If Not IsDBNull(dr("Organization")) Then
                    visit.Organization = dr("Organization")
                End If

                If Not IsDBNull(dr("CRMID")) Then
                    visit.CrmID = dr("CRMID")
                End If

                If Not IsDBNull(dr("Notes")) Then
                    visit.ContactNotes = dr("Notes")
                End If

                If Not IsDBNull(dr("DNS")) Then
                    visit.DNS = dr("DNS")
                End If

                If Not IsDBNull(dr("Region")) Then
                    visit.Region = dr("Region")
                End If

                If Not IsDBNull(dr("FirstAlert")) Then
                    visit.FirstAlertDescription = dr("FirstAlert")
                End If

                If Not IsDBNull(dr("FirstVisitReferrer")) Then
                    visit.FirstReferrer = dr("FirstVisitReferrer")
                End If

                If Not IsDBNull(dr("ProspectTypes")) Then
                    visit.ProspectTypes = dr("ProspectTypes")
                End If

                If Not IsDBNull(dr("VisitDate")) Then
                    visit.SessionStarted = dr("VisitDate")
                End If

                If Not IsDBNull(dr("SecondsOnSite")) Then
                    visit.TimeOnSite = dr("SecondsOnSite")
                End If

                If Not IsDBNull(dr("Page")) Then
                    visit.Page = dr("Page")
                End If

                visitList.Add(visit)

                dr.Close()
                Conn.Close()
            End While

            Return visitList

        Catch ex As Exception
            Throw ex
        End Try

    End Function

关联的连接初始化为:

Public Sub Init(connectionString As String) Implements IVisitorData.Init
        connString = connectionString
        Conn = New SqlConnection(connectionString)
        Conn.Close()
        If Conn.State = ConnectionState.Closed Then
            Conn.Open()
        End If
    End Sub

到目前为止我已经尝试过:

其中 none 有效。有人知道这里会发生什么吗?据我所知,datareader 只打开一次然后关闭,但一定有我遗漏的东西。

  dr.Close()
  Conn.Close()
End While

这些应该在 while 循环之外。您在关闭连接后尝试阅读。

End While
  dr.Close()
  Conn.Close()

除了 Kash 的回答之外,您最好初始化 SqlConnection class 的本地实例,这样它就在您的函数内部。默认实现无论如何都在后台使用连接池(link),因此在性能方面它没有什么不同。

Using 语句也非常有用。它提供的优点是连接在退出时自动关闭和处理。它也可以避免您当前的问题。

Using conn as new SqlConnection()
    conn.Open()
    ...
End Using

我会将连接、命令和数据读取器放入 using 语句中 MSDN。当代码在 using 块中完成时,它确保资源的处置。所以这是我要使用的代码:

using con as new sqlconnection("connection string")
     con.open()
     using command as new sqlcommand("sql string", con)
          'Your command code...
          using rdr as sqldatareader = command.executereader()
               'Your reader code...

          end using

     end using
end using

我认为这是确保您的对象得到处置的最佳方式。

HTH

韦德