以下是我登录表单的当前编码
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。
我尝试尽可能标记所有内容,并添加了大部分代码,因为人们总是要求查看它。 任何帮助表示赞赏。
答案 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并初始化它们并且代码的清洁度要好得多,那么性能就不会下降。