我四处寻找这个问题的答案,但找不到答案(部分是因为有太多的例子,根本没有设置,这不是我的问题)。
我正在围绕我的SQL数据库交互添加一些恢复例程,这样如果我遇到错误(特别是死锁或瞬间网络故障),我可以在没有数据丢失的情况下恢复事务并继续操作(这适用于工厂设备)写测试数据)。
但是,当我在同一例程中有两个+ SQL调用时,当第一个失败时,即使它成功恢复,第二个也会返回: {" ConnectionString属性尚未初始化。"}
以下是我一直在测试的代码:
If CheckAndRefreshSQL(False) Then
Dim da As SqlDataAdapter = Nothing
Dim ds As DataSet = New DataSet
Try
Dim sSqlQueryString As String = "EXECUTE dbo.usp_LogOn @LoginID = @UserName, @Password = @Pass" & AddedParms
Dim sqlCmd As SqlCommand = Nothing
sqlCmd = New SqlCommand(sSqlQueryString, m_SqlConnection)
If mSqlTransaction IsNot Nothing Then
sqlCmd.Transaction = mSqlTransaction
End If
sqlCmd.Parameters.AddWithValue("@UserName", sUser_Id)
sqlCmd.Parameters.AddWithValue("@Pass", GetPasswordHash(sUser_Id, sPassword))
da = New SqlDataAdapter(sqlCmd)
If FillWithRecovery(da, ds, False) > 0 Then
...
End If
Catch ex As Exception
...
End Try
End If
" FillWithRecovery(da,ds,False)"是恢复电话之一,取代" da.Fill(ds)"
这里的问题是" GetPasswordHash"例程也会对SQL进行一些调用。它使用相同的类范围连接,但不是相同的SqlCommand。如果哈希例程中的SQL调用由于连接而失败,则它们将尝试自己的恢复。如果恢复成功,则例程返回正确的数据。类范围SqlConnection(m_SqlConnection)中的ConnectionString保持不变。但由于某种原因,本地SqlCommand(sqlCmd)中的ConnectionString现在为空,并且" FillWithRecovery" call返回上述错误。
此代码在" GetPasswordHash"最初没有失败,必须恢复。这告诉我它可能与两者之间的常见SqlConnection有关,但我无法弄清楚是什么。我没有手动对连接本身进行任何更改。
编辑:如评论中所述,似乎SqlCommand.Connection对象是“已关闭”。在密码例程执行其重新连接之后。我可以通过将Connection对象彼此隔离,或者在连接尝试失败后重新分配SqlCommand的Connection属性来修复此问题,但是SqlCommand.Connection对象的类型是什么导致它以这种方式执行?为什么它可以在我的代码的直接范围之外关闭,但不能重新打开?似乎它是按价值分配的,也不应该是可能的,如果是参考,那么两者都应该。我是否隐式传递对重新打开SqlConnection本身时保持静态的ClientConnectionId的硬引用?