尝试将搜索功能连接到 Vb.net 中的文本框

Trying to Connect Search Feature to Textbox In Vb.net

我正在努力 link 我的搜索代码到文本框以便实际搜索并输入可能的搜索。如何将我的文本框连接到我的搜索代码以使其工作?

(一点上下文,我正在尝试在 visual basic (vb.net) 中连接一个 SQL 数据库并拥有一个可搜索的数据库或电子表格)

我尝试将代码放在下面的文本框子中。有什么帮助!

Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
    Try

        Using connection = New SqlConnection("Data Source=.\SQLEXPRESS;Initial Catalog=vbconnectionfinal;Integrated Security=True")
            ' create a new instance of the command object
            Using Command = New SqlCommand("Select * From TrueTrack WHERE UserName = @name AND DeviceType = @type", connection)

                ' parameterize the query
                Command.Parameters.Add("@name", SqlDbType.VarChar, 100).Value = "my name search"
                Command.Parameters.Add("@type", SqlDbType.VarChar, 100).Value = "my device type search"

                ' create a new instance of the data adapter object
                Using adapter = New SqlDataAdapter(Command)
                    ' fill a DataTable with the data from the adapter
                    Dim table = New DataTable()
                    adapter.Fill(table)
                    DataGridView1.DataSource = Table

                End Using
            End Using
        End Using
    Catch ex As Exception

        ' display the error
        MessageBox.Show(ex.Message)

    End Try
End Sub

您可以使用为您处理参数化的通用数据库管理器class

  • 它会将此数据库代码从您的表单中删除
  • 更容易维护您的数据库代码,因为它只会在一个地方
  • 您所要做的就是实例化数据库管理器并将 sql 和参数传递给它,这样您就不必像这样重复您的代码

数据库管理员可能是这样的:

Imports System.Data.SqlClient

Public Class DBManager
    Public Function GetDataSet(sql As String, Optional parameters As Dictionary(Of String, Object) = Nothing) As DataSet
        Using connection As New SqlConnection("Data Source=.\SQLEXPRESS;Initial Catalog=vbconnectionfinal;Integrated Security=True")
            Try
                ' Attempt to establish connection
                If connection.State <> ConnectionState.Open Then
                    connection.Open()
                End If
            
                Using cmd As New SqlCommand(sql, connection)
                    ' Add parameters
                    If parameters IsNot Nothing Then
                        For Each key As String in parameters
                            cmd.Parameters.Add(new SqlParameter(key, parameters(key)))
                        Next
                    End If
            
                    ' Fill dataset
                    Dim ds As New DataSet
                    Dim adapter As New SqlDataAdapter(cmd)
                    adapter.Fill(ds)
            
                    ' Return dataset
                    Return ds
                End Using
            Catch ex As Exception
                ' Log to some central manager or file or throw to caller
                ' Throw ex
            End Try
        End Using
        
        Return Nothing
    End Function

    Public Function ExecuteCommand(sql As String, Optional parameters As Dictionary(Of String, Object) = Nothing) As Integer
        Using connection As New SqlConnection("Data Source=.\SQLEXPRESS;Initial Catalog=vbconnectionfinal;Integrated Security=True")
            Try 
                ' Attempt to establish connection
                If connection.State <> ConnectionState.Open Then
                    connection.Open()
                End If
        
                Using cmd As New SqlCommand(sql, connection)
                    ' Add parameters
                    If parameters IsNot Nothing Then
                        For Each key As String in parameters
                            cmd.Parameters.Add(new SqlParameter(key, parameters(key)))
                        Next
                    End If
            
                    Return cmd.ExecuteNonQuery() ' Count of affected rows
                End Using
            Catch ex As Exception
                ' Log to some central manager or file or throw to caller
                ' Throw ex
            End Try
        End Using
    
        Return -1
    End Function
End Class

然后您可以在整个代码的各个地方使用这个管理器

Module Module1
    Sub Main()
        ' Sql Only
        Dim conn As New DBManager
        Dim sql As String = "SELECT * FROM TestData;"
        
        Try
            ' Remember parameters are optional
            Dim ds As DataSet = conn.GetDataSet(sql)

            If ds IsNot Nothing Then
                ' Do work on retrieved dataset
            End If
        Catch ex As Exception
            ' Catch here if db manager is throwing
        End Try
    
        ' Parameterized sql
        sql = "INSERT INTO TestData (Value) 
               VALUES (@value);"
        Dim parameters As New Dictionary(Of String, Object) From {
            { "@value", "x" }
        }
    
        Try
            Dim affectedRows As Integer = conn.ExecuteCommand(sql, parameters)

            If affectedRows = -1 Then
                ' Something went wrong
            End If
        Catch ex As Exception
            ' Catch here if db manager is throwing
        End Try
    End Sub
End Module

一种基于 TextBox 值的查询方法是使用计时器,该计时器仅在最终按键后的一段时间后运行。此示例将在最后一次更改 TextBox 后 1 秒后进行查询。它还将查询从 UI 线程卸载到计时器线程,这是一个后台线程。所以你的 UI 不会在 运行 查询

时冻结
Private ReadOnly queryTimer As New System.Threading.Timer(AddressOf runQuery, Nothing, -1, -1)
Private queryString As String
Private textChangeQueryDelay As Integer = 1000

Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
    queryString = TextBox1.Text
    queryTimer.Change(textChangeQueryDelay, -1)
End Sub

Private Sub runQuery(state As Object)
    Dim table = New DataTable()
    Using connection = New SqlConnection("Data Source=.\SQLEXPRESS;Initial Catalog=vbconnectionfinal;Integrated Security=True")
        Using Command = New SqlCommand("Select * From TrueTrack WHERE UserName = @name AND DeviceType = @type", connection)
            Command.Parameters.Add("@name", SqlDbType.VarChar, 100).Value = queryString
            Command.Parameters.Add("@type", SqlDbType.VarChar, 100).Value = "my device type search"
            Using adapter = New SqlDataAdapter(Command)
                adapter.Fill(table)
            End Using
        End Using
    End Using
    DataGridView1.Invoke(Sub() DataGridView1.DataSource = table)
End Sub

但不清楚"my name search""my device type search"从何而来。我假设名称来自 TextBox1,所以这就是代码的作用。

另一件事是您正在检查查询中的相等性,但更合适的事情(因为您正在对 TextChanged 进行操作)可能是检查类似的东西,即

Using Command = New SqlCommand("Select * From TrueTrack WHERE UserName like @name AND DeviceType = @type")
...
Command.Parameters.Add("@name", SqlDbType.NVarChar, 100).Value = "%" & querystring & "%"

这样你 return 所有结果的名称都类似于你的文本框文本。这感觉更“正确”,因为您是在用户输入时查询的。但是对于精确匹配,尤其是有多个 where 子句(我仍然没有在这个答案中调和),如评论中提到的那样对按钮单击执行一次可能是你最好的选择。

根据评论更新

您可以通过在它们的每个 TextBox_TextChanged 事件处理程序中调用查询计时器来查询名称和类型(或者让一个处理程序处理两者)

Private ReadOnly queryTimer As New System.Threading.Timer(AddressOf runQuery, Nothing, -1, -1)
Private searchName As String
Private searchType As String
Private textChangeQueryDelay As Integer = 1000

Private Sub TextBoxes_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged, TextBox2.TextChanged
    searchName = TextBox1.Text
    searchType = TextBox2.Text
    queryTimer.Change(textChangeQueryDelay, -1)
End Sub

并且在查询中您可以有条件地添加或不添加参数

Private Sub runQuery(state As Object)
    Dim table = New DataTable()
    Using connection = New SqlConnection("Data Source=.\SQLEXPRESS;Initial Catalog=vbconnectionfinal;Integrated Security=True")
        Using command = New SqlCommand()
            command.Connection = connection
            Dim commandText = "SELECT * FROM TrueTrack WHERE 1=1 "
            If Not String.IsNullOrEmpty(searchName) Then
                commandText &= " AND UserName like @name "
                command.Parameters.Add("@name", SqlDbType.VarChar, 100).Value = "%" & searchName & "%"
            End If
            If Not String.IsNullOrEmpty(searchType) Then
                commandText &= " AND DeviceType like @type "
                command.Parameters.Add("@type", SqlDbType.VarChar, 100).Value = "%" & searchType & "%"
            End If
            command.CommandText = commandText
            Using adapter = New SqlDataAdapter(command)
                adapter.Fill(table)
            End Using
        End Using
    End Using
    DataGridView1.Invoke(Sub() DataGridView1.DataSource = table)
End Sub

每次用户在文本框中键入一个字母时,我都不会拥有所有数据库代码 运行。用户在准备搜索时单击按钮怎么样?

Commandconnection 可以通过在第一行末尾添加逗号组合成一个 Using 块。

命令参数的值是您传递给函数的参数。

您不需要 DataAdapter 的额外开销。只是 Load 一个 DataTable 和一个 DataReader.

Private Function SearchDatabase(Name As String, Type As String) As DataTable
    Dim dt As New DataTable
    Using connection = New SqlConnection("Data Source=.\SQLEXPRESS;Initial Catalog=vbconnectionfinal;Integrated Security=True"),
            Command = New SqlCommand("Select * From TrueTrack WHERE UserName = @name AND DeviceType = @type", connection)
        Command.Parameters.Add("@name", SqlDbType.VarChar, 100).Value = Name
        Command.Parameters.Add("@type", SqlDbType.VarChar, 100).Value = Type
        connection.Open()
        Using reader = Command.ExecuteReader
            dt.Load(reader)
        End Using
    End Using
    Return dt
End Function

Private Sub Button1_Click() Handles Button1.Click
    Dim dt As DataTable
    Try
        dt = SearchDatabase(txtName.Text, txtType.Text)
    Catch ex As Exception
        MessageBox.Show(ex.Message)
        Exit Sub
    End Try
    'Use the values in the DataTable as needed
End Sub