You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET中DataGridView结合ComboBox更新数据库及筛选失效问题求助

问题解决与优化方案

1. 修复“Parameters不是String的成员”错误

这个错误的核心原因是你直接对字符串类型的SQL语句调用Parameters属性——字符串本身没有这个成员。正确做法是创建OleDbCommand对象并添加参数,再传递给数据适配器。

2. 重构DatabaseManager类(最优实现)

原类存在资源泄漏风险、线程使用不合理、参数化查询支持缺失等问题。重构后加入using语句管理资源,移除不必要的线程,完善参数化查询支持:

Imports System.Data.OleDb
Imports System.Configuration

Friend Class DatabaseManager
    Private ReadOnly connectionString As String = ConfigurationManager.ConnectionStrings("ConnStr").ConnectionString

    Public Function FillData(ByVal sql As String, Optional parameters As IEnumerable(Of OleDbParameter) = Nothing) As DataTable
        If String.IsNullOrWhiteSpace(sql) Then
            Throw New ArgumentException("SQL语句不能为空")
        End If

        Dim dt As New DataTable()
        ' 使用using自动释放连接、适配器等资源,无需手动管理
        Using conn As New OleDbConnection(connectionString),
              adapter As New OleDbDataAdapter(sql, conn)

            ' 添加查询参数(如果有)
            If parameters IsNot Nothing Then
                adapter.SelectCommand.Parameters.AddRange(parameters.ToArray())
            End If

            conn.Open()
            adapter.Fill(dt)

            ' 直接生成更新/插入/删除命令,无需额外线程
            Dim builder As New OleDbCommandBuilder(adapter)
            adapter.InsertCommand = builder.GetInsertCommand()
            adapter.UpdateCommand = builder.GetUpdateCommand()
            adapter.DeleteCommand = builder.GetDeleteCommand()

            ' 将适配器存入DataTable的扩展属性,确保更新时匹配正确的命令
            dt.ExtendedProperties.Add("DataAdapter", adapter)
        End Using

        Return dt
    End Function

    Public Function UpdateData(ByVal dt As DataTable) As Integer
        If Not dt.ExtendedProperties.ContainsKey("DataAdapter") Then
            Throw New InvalidOperationException("未找到对应的数据适配器,请先通过FillData加载数据")
        End If

        Dim adapter As OleDbDataAdapter = DirectCast(dt.ExtendedProperties("DataAdapter"), OleDbDataAdapter)
        Return adapter.Update(dt)
    End Function
End Class

3. 修正LoadData方法实现筛选功能

修改窗体中的LoadData方法,正确构建参数化查询以实现筛选:

Private dtData As DataTable
Private db As New DatabaseManager()

Private Sub LoadData()
    If ComboBox1.SelectedIndex > -1 Then
        ' 创建参数并指定类型,避免隐式类型转换问题
        Dim invNoParam As New OleDbParameter("@INVNO", OleDbType.VarChar)
        invNoParam.Value = CStr(ComboBox1.SelectedValue)

        ' 执行带参数的筛选查询
        dtData = db.FillData("SELECT * FROM DEMOTABLEPRODUCT WHERE INVNO = @INVNO", {invNoParam})
        gvMain.DataSource = dtData
    Else
        ' 未选择项时加载全部数据
        dtData = db.FillData("SELECT * FROM DEMOTABLEPRODUCT")
        gvMain.DataSource = dtData
    End If
End Sub

4. 关于using语句的必要性

必须使用using语句,原因如下:

  • 数据库连接、OleDbCommand、OleDbDataAdapter都实现了IDisposable接口,using块会自动调用Dispose()释放资源,避免连接池耗尽、内存泄漏。
  • 即使代码执行中发生异常,using块也会自动关闭数据库连接,无需手动判断连接状态。

5. 其他优化点

  • 移除原类中的全局conn、adapter、threadHelper,避免多线程操作时的冲突和资源泄漏。
  • 使用DataTable的ExtendedProperties存储对应适配器,确保更新操作能匹配正确的SQL命令。
  • 增加未选择ComboBox项时的默认逻辑,加载全部数据提升用户体验。

内容的提问来源于stack exchange,提问作者roy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 12:45:42