使用 LINQ 进行多条件搜索
一篇简单的文章,介绍如何使用多个条件搜索 SQL 数据库。
引言
这是一篇关于使用不同条件(一次一个或多个)对 SQL 表进行高级搜索的简单文章。
背景
您最近开发了基于 SQL 的应用程序吗?您很有可能希望实现基于多个条件的搜索。在开发基于 SQL 的应用程序时,我们经常需要能够通过部署不同的参数来搜索大量记录。例如,如果我们有一个销售表,我们可能希望仅根据收据 ID 进行搜索,或者根据收据 ID 加上客户 ID 加上销售日期等。本文处理了类似的情况,并展示了一种我们可以将这种功能实现到应用程序中的简单方法。
此应用程序将使用 lambda 表达式根据 9 个条件或字段搜索一个表。
Using the Code
首先,我们应该将 Northwind 数据库(随源代码附带)附加并安装到我们的 SQL 服务器。然后,创建一个新的 VB.NET 应用程序。给出了示例
为了访问数据库,我们需要创建一个 LINQ-To-SQL 类文件,并用 Northwind 数据库中的表填充该文件。为此,我们打开解决方案资源管理器 > 右键单击项目 > 单击添加 > 选择添加新项目 > 从已安装的模板中选择数据 > 然后选择 LINQ-To-SQL 类。让我们将 LINQ-To-SQL 文件命名为 Test。
接下来,我们打开 LINQ-To-SQL 类文件,打开服务器资源管理器,右键单击数据连接 > 选择添加连接 > 如果提示指定数据源,则选择 Microsoft SQL Server > 从服务器名称组合框中选择 SQL Server 名称以及从已安装数据库列表中选择数据库名称,然后单击确定。
之后,我们打开服务器资源管理器并打开 Northwind 数据库 > 打开表 > 选择所有表 > 将所有表拖放到我们创建的 LINQ-To-SQL 文件上。
好的,接下来,我们创建高级搜索表单。在此示例中,我们将搜索 Orders
表中的 Northwind
数据库。现在,我们可以使用几个参数进行搜索,例如 客户 ID
、员工 ID
、货运公司 ID
、OrderDate
、Required Date
等。在此示例中,共有 9 个搜索参数可供使用。
好的,现在是激动人心的部分。我们右键单击该表单,然后单击查看代码。首先,我们必须创建 LINQ-To-SQL 类的实例。让我们将此实例称为 datatest
。
''
'' Creating Instance Of LINQ-To-SQL Class
''
Dim datatest as new TestDataContext
接下来,我们创建一个子程序,将所有客户、货运公司和员工绑定到它们各自的 combobox
控件。
''Binding Elements To Combobox.
''
Private Sub MainBind()
Try
''Binding Customer Combo
CustomerCombo.DataSource = From l In datatest.Customers Select l.CustomerID, l.CompanyName
CustomerCombo.ValueMember = "CustomerID"
CustomerCombo.DisplayMember = "CompanyName"
CustomerCombo.SelectedValue = -1
''Binding Shippers ComboBox
ShippersCombo.DataSource = From l In datatest.Shippers Select l.ShipperID, l.CompanyName
ShippersCombo.ValueMember = "ShipperID"
ShippersCombo.DisplayMember = "CompanyName"
ShippersCombo.SelectedValue = -1
''Binding Employee ComboBox
EmployeeCombo.DataSource = From l In datatest.Employees Select l.EmployeeID, l.FirstName
EmployeeCombo.ValueMember = "EmployeeID"
EmployeeCombo.DisplayMember = "FirstName"
EmployeeCombo.SelectedValue = -1
Catch ex as Exception
MessageBox.Show(ex.Message, "LINQ Advanced Search", _
MessageBoxButtons.OK, MessageBoxIcon.Information)
End Try
End Sub
完美,接下来我们定义默认构造函数并在构造函数内部调用 MainBind
过程。这将确保在运行应用程序时将元素映射到 combobox
。
Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
''We Call MainBind Procedure To Bind Data To Respective Combobox's
MainBind()
End Sub
太棒了,之后,我们返回到表单设计并双击搜索按钮以生成单击事件。
在该事件中,我们复制以下代码
''
''
''Filtering Orders table based on user criteria
''
''Select the entire Order table and put result in an Anonymous Type variable called SrchResult
Dim SrchResult = From k In datatest.Orders Select k
Dim flag As Boolean = False
Try
''Filter All Orders Which Have The Selected Customer ID
If CustomerCombo.SelectedValue <> Nothing Then
flag = True
SrchResult = SrchResult.Where(Function(p) p.CustomerID = _
CStr(CustomerCombo.SelectedValue))
End If
''Filter All Orders Which Have The Selected Shipper ID
If ShippersCombo.SelectedValue <> Nothing Then
flag = True
SrchResult = SrchResult.Where(Function(p) p.ShipVia = _
CInt(ShippersCombo.SelectedValue))
End If
''Filter All Orders Which Have The Selected Employee ID
If EmployeeCombo.SelectedValue <> Nothing Then
flag = True
SrchResult = SrchResult.Where(Function(p) p.EmployeeID = _
CInt(EmployeeCombo.SelectedValue))
End If
''Filter All Orders Which Have The Selected Order Date
If OrderDatetxt.Text <> Nothing Then
flag = True
SrchResult = SrchResult.Where(Function(p) p.OrderDate = CDate(OrderDatetxt.Text))
End If
''Filter All Orders Which Have The Selected Required Date
If RequiredDateTxt.Text <> Nothing Then
flag = True
SrchResult = SrchResult.Where(Function(p) p.RequiredDate = CDate(RequiredDateTxt.Text))
End If
''Filter All Orders Which Have The Selected Shipped Date
If ShippedDateTxt.Text <> Nothing Then
flag = True
SrchResult = SrchResult.Where(Function(p) p.ShippedDate = CDate(ShippedDateTxt.Text))
End If
''Filter All Orders Which Have The Selected Shipped Address
If ShippedAddressTxt.Text <> "" Then
flag = True
SrchResult = SrchResult.Where(Function(p) p.ShipAddress = CStr(ShippedAddressTxt.Text))
End If
''Filter All Orders Which Have The Selected Shipped City
If ShippedCityTxt.Text <> "" Then
flag = True
SrchResult = SrchResult.Where(Function(p) p.ShipCity = CStr(ShippedCityTxt.Text))
End If
''Filter All Orders Which Have The Selected Shipped Country
If ShippedCountryTxt.Text <> "" Then
flag = True
SrchResult = SrchResult.Where(Function(p) p.ShipCountry = CStr(ShippedCountryTxt.Text))
End If
If flag = False Then
MessageBox.Show("Please Select A Criteria For Search", _
"LINQ Advanced Search", MessageBoxButtons.OK, MessageBoxIcon.Information)
Exit Sub
End If
If SrchResult.Any Then
'' Sort using Customer ID
SrchResult = SrchResult.OrderBy(Function(k) k.CustomerID)
''Bind result to the gridview
SearchResultGrid.DataSource = SrchResult
Else
MessageBox.Show("There Is No Record That Matchs Your Criteria.", _
"LINQ Advanced Search", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
Catch Ex As Exception
MessageBox.Show(Ex.Message, "LINQ Advanced Search", _
MessageBoxButtons.OK, MessageBoxIcon.Information)
End Try
就是这样。但在我们测试应用程序之前,让我们先看看代码。代码的作用很简单:首先,我们只需将整个表复制到一个名为 SrchResult
的匿名类型中,然后我们检查控件(无论是 combobox
还是 textbox
)是否选择了任何值或在其上写入任何值,如果确实如此,代码将使用 Lambda 函数仅过滤表中与所选值匹配的记录。它将对所有 9 个搜索条件重复此任务。很简单,对吧?
现在让我们运行应用程序以进行测试。从 客户组合框
中,我选择了第一个元素来执行搜索。结果如下所示
让我们通过从货运公司组合框中选择一个货运公司来进一步过滤。结果如下所示
或者通过从 员工组合框
中选择 员工
。结果如下所示
或者通过以下格式(YY/MM/DD)在订单日期文本框中写入订单日期。结果如下所示
毋庸置疑,我们可以一次使用 2 个以上的搜索参数。例如,我们可以在最后一个示例中添加发货国家/地区参数
结论
此示例展示了 LINQ 的主要优势之一:以非常简单快捷的方式执行查询。这些使用 Lambda 函数的查询也可以扩展到包括多个表,从而创建更强大的查询和可伸缩性。