通过 datagridview 搜索值
Posted
技术标签:
【中文标题】通过 datagridview 搜索值【英文标题】:Searching values via a datagridview 【发布时间】:2015-11-13 20:30:42 【问题描述】:我尝试通过在文本框中输入文本,然后使用 SQL 查询数据库,然后在 datagridview 中显示结果来搜索数据库中的特定值。
代码如下:
Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtSearch.TextChanged
Connection.Open()
Dim dataTable As New DataTable
Dim dataSet As New DataSet
dataSet.Tables.Add(dataTable)
Dim dataAdapter As New OleDbDataAdapter
Dim SQLQuery As String
SQLQuery = <sql>
SELECT *
FROM Students
WHERE StudentFirstName = @StudentFirstName
</sql> .Value
dataAdapter = New OleDbDataAdapter(SQLQuery, Connection)
dataAdapter.SelectCommand.Parameters.Add("@StudentFirstName", SqlDbType.Text).Value = txtStudentFirstname.Text
dataAdapter.Fill(dataTable)
dgrStudentDatabaseViewer.DataSource = dataTable.DefaultView
ShowItems()
Connection.Close()
End Sub
调用 ShowItems() 刷新 datagridview 这里是它的代码
Private Sub ShowItems() ' the following delcleration are used for displaying the contents of the table
Dim dataAdapter As New OleDbDataAdapter
Dim DataTable As New DataTable
Dim DataSet As New DataSet
Dim SQLQuery As String = <sql>SELECT * FROM Students</sql>
DataSet.Tables.Add(DataTable)
dataAdapter = New OleDbDataAdapter(SQLQuery, Connection)
dataAdapter.Fill(DataTable) ' fills the content from the database into the table in vb net
dgrStudentDatabaseViewer.DataSource = DataTable.DefaultView
Connection.Close()
End Sub
目前,当我尝试搜索时,什么也没有发生,datagridview 的内容保持原样。我认为这可能与我的 SQL 查询的 XML 文字有关,但无法弄清楚。
提前致谢。
【问题讨论】:
首先,每次用户键入字母时,您都会触发查询。如果我输入“h..a..s..a..n”,在我完成之前它不会找到“H”或“ha”等姓氏。因此,将第一部分移动到搜索按钮单击中。其次,第一个块中的代码正确使用了 xml 文字(.Value),第二个则没有。使用数据源不需要整个 ShowItems 方法。两个块都没有使用它们声明的数据集。 如果您要停止一遍又一遍地重新创建数据库对象,您可以使用行过滤器属性:myStudentDataView.RowFilter = String.Format("StudentName = 0", textbox1.Text)
@Plutonix 首先,当您说第一部分时,您指的是哪一部分。其次,我将在哪里放置行过滤器。
第一部分 == 你的第一个代码块 第二部分 == 你的第二个代码块。您还应该打开 Option Strict。即使搜索确实有效,您也可以通过调用运行新 SQL 的 ShowItems
来撤消显示的内容。我认为您不能使用 RowFilter,因为您没有持久的 DataTable
【参考方案1】:
一遍又一遍地创建New
DB 对象会妨碍您。如果DataAdapter
是表单级别的变量,您将需要编写更少的代码:
Public Class Form1
' declare some persistant DB objects
Private myDT As DataTable
Private myDA As OleDbDataAdapter
Private myStudentsDataView As DataView
Private dbConnStr As String = "(your connection string)"
这些只是声明的,没有它们的实例(没有New
)。但是在哪里声明它们决定了Scope
。它们将一直存在,直到表单关闭(或者您用Dim
和/或New
覆盖它们)。表单加载:
' initialize the objects
Dim sql = "SELECT A, B, C, D... FROM Students"
' this is the ONLY place you use NEW
' with these objects
myDT = New DataTable()
' The Adapter can create its own Connection
' and SelectCommand
myDA = New OleDbDataAdapter(sql, dbConnStr)
Dim myCB As New OleDbCommandBuilder(da)
' "teach" the DA how to Update and Add:
myDA.UpdateCommand = myCB.GetUpdateCommand
myDA.InsertCommand = myCB.GetInsertCommand
myDA.DeleteCommand = myCB.GetDeleteCommand
myDA.Fill(myDT)
myDA.FillSchema(myDT, SchemaType.Source)
myStudentsDataView = myDT.DefaultView
dgvStudents.DataSource = myStudentsDataView
DataAdapter
需要一个连接对象才能工作,但正如评论所述,适配器可以创建自己的,而不是显式创建一个。它将根据需要打开和关闭它。 SelectCommand
也是如此 - 它将根据传递的 SELECT SQL 语句创建自己的。
请注意,最好按照您希望列在DataTable
中出现的顺序指定每一列。重要的是最后 that DataAdapter
知道如何删除、插入和更新行。只要您不销毁或替换它,您就不必编写任何 SQL 来添加或更改行!
在大多数情况下,DataTable
用作 DGV 的 DataSource
:
myDGV.DataSource = myDT
DGV 将创建所需的列并将数据显示为行。当用户输入单元格时,这些更改会反映在 DataTable
中,因此无需任何代码将其恢复。
如果用户编辑DataGridView
中的数据,您只需将更改发送回数据库:
myDa.Update(myDT)
在这种情况下,根据前面的问题,数据来自文本控件而不是 DGV。所以:
Private Sub AddStudent()
' no need to (RE)create DataAdapter
' add the data to a new row:
Dim dr = myDT.NewRow
dr.Item("FirstName") = textbox1.text
dr.Item("LastName") = textbox2.text
' etc etc
' add the new row to the datatable
myDT.Rows.Add(dr)
' with a persistent DA, this is all you need to add a row:
myDA.Update(myDT)
End Sub
我们“教”了DataAdapter
如何在表单加载中更新一行,因此实际更新数据库(一旦数据在 DT 中)只需一行代码:myDA.Update(myDT)
。
DataTable
跟踪每一行是新的、更改的还是删除的,因此myDA.Update(myDT)
对每一行采取适当的操作。如果系统是多用户的,你可以接受其他用户的更改:
myDa.Fill(myDT)
搜索也很简单:
Private Sub Search(txt As String)
myStudentsDataView.RowFilter = String.Format("LastName = '0'", txt)
要删除过滤器:
myStudentsDataView = myDT.DefaultView
如果/当您的DataAdapter
无法添加、插入、更新或删除时,这意味着您在某处创建了一个New
。不要那样做。同样,myDataView
将显示 myDT
中的任何内容,直到您创建新的 DT 或 DV 或更改 RowFilter
。
【讨论】:
会的。非常感谢。 很好的答案 plutonix。我以前也从你那里学会了使用 Using。但是根据您上面的指南,只有一个问题。如果数据库包含至少 2k 行记录,应用程序在将新更改更新回数据库时会开始滞后吗? @Student 通常 2k 行非常小。数据适配器很智能——它只会更新新的、更改的或删除的行;所以区别是发送了许多小的更改,或者一批几个。 @Plutonix 我明白了。所以建议使用 dataadapter 来更新它而不是查询新的更新字符串,对吗?我想我会花一整夜把它改成你上面的例子:) 它可以更好、更简单、更少的数据库流量。这取决于应用程序。简单地添加/编辑基础项目的应用程序的一部分可以使用它;将多个表连接在一起的另一部分(例如 Order、OrderItems、ServiceLineItem 等)无法使用它。因此,对于多个表,这取决于它们如何/是否相关;简单的标题细节仍然可以工作,而不是 DataSet 我通常有 2 个不同的类在事务中处理每个类。如果基本查询是SELECT *...
并且代码在删除、更改后重新运行该查询,则适配器可能更有效。以上是关于通过 datagridview 搜索值的主要内容,如果未能解决你的问题,请参考以下文章