VB.NET登录窗体判断OLEDB连接状态抛出未将对象引用设置实例错误
错误根因定位
空引用异常的触发逻辑非常直接:
- 代码中仅在类级别声明了
Dim con As OleDbConnection,全程没有通过New关键字创建OleDbConnection的实例,这个变量的默认值为Nothing(即未指向任何实际内存对象) - 当代码运行到
If con.State = ConnectionState.Closed Then行时,试图从Nothing对象上读取State属性,就会直接抛出「未将对象引用设置到对象实例」的运行时错误。
原代码还存在两个暂未触发、但后续运行必然出问题的逻辑/语法缺陷:
- 空值校验逻辑不闭环:当用户名/密码文本框为空弹出错误提示后,没有终止按钮事件的后续流程,代码会继续进入数据库查询环节
- OleDb参数写法不符合方法定义:
login.Parameters.AddWithValue("@UserName", OleDbType.VarChar).Value = ...的写法完全错误,会导致查询条件失效,永远匹配不到正确的用户记录。
可落地修复步骤
- 第一步:完成连接对象的实例化,从根源上解决空引用问题。如果保留原有的全局连接写法,可以在窗体加载事件中使用之前定义好的连接片段拼接完整连接字符串,创建实际的连接实例:
Private Sub LoginForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load ' 拼接完整连接串,实例化con对象 con = New OleDb.OleDbConnection($"{dbProvider}{dbSource}") End Sub
- 第二步:补全空值校验的中断逻辑,校验不通过时直接退出当前事件,避免无效查询:
If txtUserName.Text.Trim() = String.Empty Or txtPassword.Text.Trim() = String.Empty Then MessageBox.Show("Please enter correct username or password", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) ' 新增中断逻辑,不再执行后续代码 Exit Sub End If
- 第三步:修正OleDb参数的添加写法,匹配ADO.NET的参数方法签名,保证查询条件生效:
' 正确参数写法:Add方法需指定参数名、数据类型、字段长度、参数值 login.Parameters.Add("@UserName", OleDbType.VarChar, 50).Value = txtUserName.Text.Trim() login.Parameters.Add("@Password", OleDbType.VarChar, 50).Value = txtPassword.Text.Trim()
- 优化建议:不建议将数据库连接作为类级别的全局变量长期持有,可使用
Using块包裹连接对象,实现查询完成后自动释放连接资源,避免数据库连接泄漏。
修复后可直接运行的核心代码
Public Class LoginForm ' 仅保存连接字符串常量,不再全局持有连接实例 Private ReadOnly dbProvider As String = "Provider=Microsoft.ACE.OLEDB.12.0;" Private ReadOnly dbSource As String = "Data Source=C:\Users\Windows10\Desktop\dbInventory.accdb;" Private Sub btnRegister_Click(sender As Object, e As EventArgs) Handles btnRegister.Click Me.Hide() RegistrationForm.Show() End Sub Private Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click ' 空值校验 If String.IsNullOrWhiteSpace(txtUserName.Text) Or String.IsNullOrWhiteSpace(txtPassword.Text) Then MessageBox.Show("Please enter correct username or password", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) Exit Sub End If ' 即时创建连接,Using块自动释放资源 Dim connString As String = $"{dbProvider}{dbSource}" Using con As New OleDb.OleDbConnection(connString) Using loginCmd As New OleDb.OleDbCommand( "SELECT COUNT(*) FROM tbl_EmployeesInfo WHERE [UserName] = @UserName AND [Password] = @Password", con ) ' 正确传递查询参数 loginCmd.Parameters.Add("@UserName", OleDbType.VarChar, 50).Value = txtUserName.Text.Trim() loginCmd.Parameters.Add("@Password", OleDbType.VarChar, 50).Value = txtPassword.Text.Trim() ' 打开连接执行查询 con.Open() Dim loginMatchCount As Integer = Convert.ToInt32(loginCmd.ExecuteScalar()) If loginMatchCount > 0 Then Me.Hide() InventoryForm.Show() Else MessageBox.Show("UserName or Password is wrong. Try again", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) txtUserName.Clear() txtPassword.Clear() End If End Using End Using End Sub End Class
内容的提问来源于stack exchange,提问作者Gnolab
相关产品推荐
相关产品推荐

