ConnectionString属性。连接的当前状态

时间:2015-11-27 22:07:34

标签: vb.net ms-access connection-string oledb

以下是我登录表单的当前编码

 Option Strict On
'-------------------------------------------
' Imports required for DB Connectivity
'------------------------------------------
Imports System.Data.OleDb
Imports ShadowLogin.GlobalVariables

Public Class ShadowLogin
Dim Main As New ShadowMain

'-------------------------------------------------------------------------------------------------------------------------------
' Establish Database Connectivity parameters
'-------------------------------------------------------------------------------------------------------------------------------
Dim cnnOLEDB As New OleDbConnection
Dim cmdOLEDB As New OleDbCommand
Dim strConnectionString As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Environment.CurrentDirectory & "\shadow.mdb"


'-------------------------------------------------------------------------------------------
' System Login
'-------------------------------------------------------------------------------------------
Private Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click

    Dim selectedbutton As New RadioButton
    Dim Cancel As Boolean

    'Checks RedID is numerical digits only 
    If Not IsNumeric(txtRedID.Text) Then
        MsgBox("Please Check RedID.", vbInformation)

        'you may also consider erasing it
        txtRedID.Text = ""
        txtRedID.Focus()
        Exit Sub

        'checks that RedID is 9 characters long
    ElseIf txtRedID.Text.Length < 9 Then
        txtRedID.Focus()
        txtRedID.SelectAll()
        MsgBox("Please Check RedID", MsgBoxStyle.Exclamation)
        Exit Sub
    Else
        Cancel = True
    End If

    'Checks that a password has been entered
    If txtPassword.Text = "" Then
        MsgBox("Please Enter a Password", MsgBoxStyle.Exclamation, MsgBoxStyle.OkOnly)
        Exit Sub
    End If

    'if radiobutton is selected then continue
    If GroupBox1.SelectedRadioButton(selectedbutton) Then
        Main = New ShadowMain
        'Checks if radiobutton is selected and hides tabs 
        If optStudent.Checked = True Then
            ShadowMain.TabControl1.TabPages.Remove(ShadowMain.TabPage2)
            ShadowMain.TabControl1.TabPages.Remove(ShadowMain.TabPage3)

        ElseIf optFaculty.Checked = True Then
            ShadowMain.TabControl1.TabPages.Remove(ShadowMain.TabPage1)
            ShadowMain.TabControl1.TabPages.Remove(ShadowMain.TabPage3)

        ElseIf optDepartmentChair.Checked = True Then
            ShadowMain.TabControl1.TabPages.Remove(ShadowMain.TabPage1)
            ShadowMain.TabControl1.TabPages.Remove(ShadowMain.TabPage2)

        End If
    Else

        'if no radiobutton is selected display messagebox
        MsgBox("Please select a role")
        Exit Sub
    End If

    ' Check which role is selected and proceed accordingly


    '--------------------------------------------------------------------------------
    ' Student Role Login
    '--------------------------------------------------------------------------------
    If optStudent.Checked Then 'If user select a student role


        ' Let's Search for the User and Password

        cnnOLEDB.ConnectionString = strConnectionString
        cnnOLEDB.Open()
        ' Select the Student Record base on User Input
        cmdOLEDB.CommandText = "SELECT * FROM [Student] WHERE [SRedID]=" & txtRedID.Text
        cmdOLEDB.Connection = cnnOLEDB
        Dim rdrOLEDB As OleDbDataReader = cmdOLEDB.ExecuteReader

        'If we can find a match..
        If rdrOLEDB.Read = True Then
            ' See that the User, Password and Active status okay
            If rdrOLEDB.Item(0).ToString = txtRedID.Text And rdrOLEDB.Item(9).ToString = txtPassword.Text And rdrOLEDB.Item(13).ToString = "True" Then
                'Populate global userID (for future needs)
                userID = txtRedID.Text()
                'Populate a role for (for future needs)
                role = "Student"
                'Cleanup the login form
                Call LoginCleanup()
                ' Populate personal data in the Student Home
                ShadowMain.lblLName.Text = rdrOLEDB.Item(1).ToString
                ShadowMain.lblFName.Text = rdrOLEDB.Item(3).ToString
                ShadowMain.lblMIn.Text = rdrOLEDB.Item(2).ToString
                ShadowMain.lblAddOne.Text = rdrOLEDB.Item(5).ToString
                ShadowMain.lblCity.Text = rdrOLEDB.Item(6).ToString
                ShadowMain.lblState.Text = rdrOLEDB.Item(7).ToString
                ShadowMain.lblZip.Text = rdrOLEDB.Item(8).ToString
                ShadowMain.lblPhone.Text = rdrOLEDB.Item(10).ToString
                ShadowMain.lblEmail.Text = rdrOLEDB.Item(15).ToString
                'Show student home
                ShadowMain.Show()
                ' Close table and database connection (required) 
                rdrOLEDB.Close()
                cnnOLEDB.Close()
            Else
                'If user / password don't match
                MsgBox("Sorry, username or password not found", MsgBoxStyle.OkOnly, "Invalid Login")
                ' clear login window
                Call ClearLogin()
                ' Close table and database connection (required)
                rdrOLEDB.Close()
                cnnOLEDB.Close()
            End If
        Else
            ' Close table and database connection (required)
            rdrOLEDB.Close()
            cnnOLEDB.Close()
            'If user / password don't match
            MsgBox("Sorry, username or password not found", MsgBoxStyle.OkOnly, "Invalid Login")
            Call ClearLogin()
        End If


        '--------------------------------------------------------------------------------
        ' Faculty Role Login
        '--------------------------------------------------------------------------------

    ElseIf optFaculty.Checked Then

        ' Let's Search for the User and Password
        cnnOLEDB.Close()
        cnnOLEDB.ConnectionString = strConnectionString
        cnnOLEDB.Open()
        cmdOLEDB.CommandText = "SELECT * FROM [Faculty] WHERE [FRedID]=" & txtRedID.Text
        cmdOLEDB.Connection = cnnOLEDB
        Dim rdrOLEDB As OleDbDataReader = cmdOLEDB.ExecuteReader


        'If we can find a match.
        If rdrOLEDB.Read = True Then
            If rdrOLEDB.Item(0).ToString = txtRedID.Text And rdrOLEDB.Item(5).ToString = txtPassword.Text And rdrOLEDB.Item(9).ToString = "True" Then
                userID = txtRedID.Text()
                role = "Faculty"
                Call LoginCleanup()
                ShadowMain.lblLastNameFac.Text = rdrOLEDB.Item(2).ToString
                ShadowMain.lblFirstNameFac.Text = rdrOLEDB.Item(3).ToString
                ShadowMain.lblMiddleIntFac.Text = rdrOLEDB.Item(4).ToString
                ShadowMain.lblOfficeFac.Text = rdrOLEDB.Item(8).ToString
                ShadowMain.lblPhoneFac.Text = rdrOLEDB.Item(6).ToString
                ShadowMain.lblEmailFacl.Text = rdrOLEDB.Item(7).ToString
                ShadowMain.Show()
                rdrOLEDB.Close()
                cnnOLEDB.Close()
            Else
                MsgBox("Sorry, username or password not found", MsgBoxStyle.OkOnly, "Invalid Login")
                Call ClearLogin()
                rdrOLEDB.Close()
                cnnOLEDB.Close()
            End If
        Else
            rdrOLEDB.Close()
            MsgBox("Sorry, username or password not found", MsgBoxStyle.OkOnly, "Invalid Login")
            Call ClearLogin()
        End If



        '--------------------------------------------------------------------------------
        ' Department Chair Role Login
        '--------------------------------------------------------------------------------

    ElseIf optDepartmentChair.Checked Then
        ' Let's Search for the User and Password
        Dim rdrOLEDB As OleDbDataReader = cmdOLEDB.ExecuteReader
        cnnOLEDB.Close()
        cnnOLEDB.ConnectionString = strConnectionString
        cnnOLEDB.Open()
        cmdOLEDB.CommandText = "SELECT [DCRedID,Password] FROM [DepartmentChair] WHERE [DCRedID]=" & txtRedID.Text
        cmdOLEDB.Connection = cnnOLEDB


        'If we can find a match..
        If rdrOLEDB.Read = True Then
            If rdrOLEDB.Item(0).ToString = txtRedID.Text And rdrOLEDB.Item(1).ToString = txtPassword.Text Then
                userID = txtRedID.Text()
                role = "Department Chair"
                Call LoginCleanup()
                ShadowMain.Show()
                rdrOLEDB.Close()
                cnnOLEDB.Close()
            Else
                MsgBox("Sorry, username or password not found", MsgBoxStyle.OkOnly, "Invalid Login")
                Call ClearLogin()
                rdrOLEDB.Close()
                cnnOLEDB.Close()
            End If
        Else
            rdrOLEDB.Close()
            cnnOLEDB.Close()
            MsgBox("Sorry, username or password not found", MsgBoxStyle.OkOnly, "Invalid Login")
            Call ClearLogin()
        End If
    End If


End Sub

我现在遇到的问题是,如果我第一次登录失败,然后第二次尝试登录,我会收到错误:

  

不允许更改&#39; ConnectionString&#39;属性。连接的当前状态是打开的。

我抬头找到了一个解决方案,说我需要确保我的连接在手边关闭,它解决了这个问题,但现在我遇到了这个问题:

  

读取器关闭时无效尝试调用Read。

我尝试尽可能标记所有内容,并添加了大部分代码,因为人们总是要求查看它。 任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:0)

我真的建议你将较大的代码块拆分成较小的部分。实际上这段代码很难阅读和调试。要控制连接状态,您必须向Connection.Close和DataReader.Close引入虚假调用,但正如您所看到的,这非常容易出错,因为您无法确保覆盖每个代码路径。

相反,如果您引入较小的代码块,则可以更好地控制打开和关闭与相关阅读器的连接。

例如

If optStudent.Checked Then 'If user select a student role
    '--------------------------------------------------------------------------------
    ' Student Role Login
    '--------------------------------------------------------------------------------
   HandleStudentRole()
ElseIf optFaculty.Checked Then
    '--------------------------------------------------------------------------------
    ' Faculty Role Login
    '--------------------------------------------------------------------------------
     HandleFacultyRole()

ElseIf optDepartmentChair.Checked Then
    '--------------------------------------------------------------------------------
    ' Department Chair Role Login
    '--------------------------------------------------------------------------------
    HandleDepartmentRole()
End If

现在你可以编写较小的代码块,确保每个块打开和关闭连接和阅读器(这里我将显示学生角色的块,但另一个是相似的)

Private Sub HandleStudenRole()
  ' Let's Search for the User and Password

    Using cnnOLEDB = new OleDbConnection(strConnectionString)
    Using cmdOleDB = new OleDbCommand("SELECT * FROM [Student] WHERE [SRedID]= @studentID", cnnOleDB)
       cnnOLEDB.Open()
       ' Select the Student Record base on User Input
       cmdOleDb.Parameters.Add("@studentID", OleDbType.VarWChar).Value = Convert.ToInt32(txtRedID.Text)
       Using rdrOLEDB = cmdOLEDB.ExecuteReader
           'If we can find a match..
          If rdrOLEDB.Read = True Then
             ......
          Else
            'If user / password don't match
            MsgBox(....)
            ' clear login window
            Call ClearLogin()
          End If
       End Using
    End Using
    End Using
End Sub

我使用了Using statement,它允许删除您编写的所有代码以关闭连接和阅读器。如果出现异常,则每当代码流从using块退出时,使用将确保调用Close和Dispose方法。当然查询是参数化的(尽管在这种情况下很难利用Sql注入)

另请注意,在我的 HandleStudentRole 块中,变量 cnnOLEDB cmdOLEDB 是局部变量。您不再需要在全球范围内声明它们。如果您在每次需要时对它们进行declere并初始化它们并且代码的清洁度要好得多,那么性能就不会下降。