如何:使用 ASP.NET 4 QueryExtender 控件






4.56/5 (9投票s)
本文演示如何使用 ASP.NET 4 中新添加的 QueryExtender 控件,通过声明式语法在网页上动态过滤数据。
引言
QueryExtender 控件是 ASP.NET 新增的控件,用于创建数据源检索数据的过滤器,而无需在数据源中使用显式的 Where 子句。该控件可以通过声明式语法在 Web 页面的标记中用于过滤数据。
背景
对于创建数据驱动型 Web 页面的开发人员来说,过滤数据是一项非常常见的任务。在互联网上随处可见过滤器,无论我们浏览哪个网站,都有过滤器方便我们访问数据存储。术语可能不同;有些地方只是过滤器,有些地方是搜索,有些地方是查找,或者干脆是高级搜索!过滤通过仅显示满足指定条件的记录来排除数据源中的数据。过滤使您能够在网页上呈现数据集中数据的不同视图,而不会影响数据集中的数据。
通常,过滤需要您创建 Where 子句来应用于查询数据源的命令。但是,LinqDataSource
控件的 Where
属性并未公开 LINQ 中提供的全部功能。为了解决这个问题,并使网页数据过滤更轻松便捷,ASP.NET 4 推出了 QueryExtender
控件,该控件允许设计人员使用声明式语法和极少的代码(您无需在数据源上创建显式查询)将过滤应用于数据源。它提供了比 Where 子句更丰富的过滤表达式。
使用代码
可以将 QueryExtender
控件添加到 EntityDataSource
或 LinqDataSource
控件中,以过滤这些控件返回的数据。它基于 LINQ,因此过滤器在数据发送到页面之前应用于数据库服务器,从而实现高效的过滤操作。
QueryExtender
控件支持多种过滤选项。下文将介绍这些选项并提供使用示例。
步骤 1:添加网页
首先,我们必须有一个网页,我们希望在其中过滤数据并以不同的视图呈现。我正在创建一个简单的网页 default.aspx,其中包含一些用于演示 QueryExtender
功能所需的控件。表单元素显示在代码块中。
<form id="form1" runat="server">
<div>
<table>
<tr>
<td>
Filter Results by Name:
</td>
<td>
<asp:TextBox ID="TextBoxName" runat="server" ></asp:TextBox>
</td>
</tr>
<tr>
<td>
Filter Results by ID between
</td>
<td>
<asp:TextBox ID="TextBoxFrom" runat="server"
Width="50px"></asp:TextBox>
and <asp:TextBox ID="TextBoxTo" runat="server"
Width="50px"></asp:TextBox>
</td>
</tr>
<tr>
<td>
Make Flag:
</td>
<td>
<asp:CheckBox ID="CheckBoxMakeFlag" runat="server" />
</td>
</tr>
</table>
<asp:Button ID="btnFilter" runat="server" Text="Filter" />
</div>
</form>
步骤 2:添加 LINQ 数据源
QueryExtender
控件基于 LINQ,这意味着它可以与 LinqDataSource
和 EntityDataSource
控件一起使用。让我们为 AdventureWorks 数据库中的 Products 表添加一个 LinqDataSource
(这是 SQL Server 提供的示例数据库,您可以从 SQL Server 安装选项 -> 示例数据库中安装)。
<asp:LinqDataSource ID="ldsMyLinqDataSource"
runat="server" TableName="Products"
Select="new (ProductID, Name, ProductNumber, MakeFlag, FinishedGoodsFlag,
Color, StandardCost,
ListPrice, Size, Class, DaysToManufacture, ModifiedDate)">
</asp:LinqDataSource>
注意:为简单起见,我仅包含 Products 表中的几个字段,这些字段将在各种过滤选项中使用。
步骤 3:添加 QueryExtender 控件
下一步是添加一个 QueryExtender
控件,该控件将定位到我们上面添加的 LinqDataSource
。这很简单(请记住,声明式语法!)。
<asp:QueryExtender ID="ctlMyQueryExtender"
runat="server" TargetControlID="ldsMyLinqDataSource"> </asp:QueryExtender>
步骤 4:过滤选项
现在我们的数据源和 QueryExtender
都已准备就绪,让我们看看可用于它的表达式选项。
SearchExpression
这是一个基于文本的搜索。QueryExtender
控件在指定字段中执行文本搜索,搜索字段或字段中的字符串值,并将其与指定的字符串值进行比较。该表达式可以执行“以...开头”、“包含”或“以...结尾”的搜索。例如,您可以将文本输入到文本框控件中,并使用该表达式在从数据源控件返回的列中搜索该文本。
让我们修改 QueryExtender
控件以包含 SearchExpression。因此,我们的代码现在变为
<asp:QueryExtender ID="ctlMyQueryExtender"
runat="server" TargetControlID="ldsMyLinqDataSource">
<asp:SearchExpression DataFields="Name" SearchType="StartsWith">
<asp:ControlParameter ControlID="TextBoxName" />
</asp:SearchExpression>
</asp:QueryExtender>
RangeExpression
这是一个范围搜索表达式。它使用一对值来定义一个范围。该表达式确定列中的值是否落在最小和最大范围之间。让我们将其添加到我们现有的 QueryExtender
控件中。修改后的代码是
<asp:QueryExtender ID="ctlMyQueryExtender" runat="server"
TargetControlID="ldsMyLinqDataSource">
<asp:SearchExpression DataFields="Name" SearchType="StartsWith">
<asp:ControlParameter ControlID="TextBoxName" />
</asp:SearchExpression>
<asp:RangeExpression DataField="ProductID"
MaxType="Inclusive" MinType="Inclusive">
<asp:ControlParameter ControlID="TextBoxFrom" />
<asp:ControlParameter ControlID="TextBoxTo" />
</asp:RangeExpression>
</asp:QueryExtender>
OrderByExpression
此表达式允许您按指定的列和排序方向对数据进行排序。添加到我们现有的 QueryExtender 示例中
<asp:QueryExtender ID="ctlMyQueryExtender"
runat="server" TargetControlID="ldsMyLinqDataSource">
<asp:SearchExpression DataFields="Name" SearchType="StartsWith">
<asp:ControlParameter ControlID="TextBoxName" />
</asp:SearchExpression>
<asp:RangeExpression DataField="ProductID"
MaxType="Inclusive" MinType="Inclusive">
<asp:ControlParameter ControlID="TextBoxFrom" />
<asp:ControlParameter ControlID="TextBoxTo" />
</asp:RangeExpression>
<asp:OrderByExpression DataField="ListPrice" Direction="Descending">
<asp:ThenBy DataField="ProductID" Direction="Ascending" />
</asp:OrderByExpression>
</asp:QueryExtender>
PropertyExpression
此表达式将列的属性值与指定值进行比较。例如,您可以将布尔值与数据库中 Products 表的 discontinued 列中的值进行比较。请参阅下面的代码。
<asp:QueryExtender ID="ctlMyQueryExtender"
runat="server" TargetControlID="ldsMyLinqDataSource">
<asp:SearchExpression DataFields="Name" SearchType="StartsWith">
<asp:ControlParameter ControlID="TextBoxName" />
</asp:SearchExpression>
<asp:RangeExpression DataField="ProductID" MaxType="Inclusive" MinType="Inclusive">
<asp:ControlParameter ControlID="TextBoxFrom" />
<asp:ControlParameter ControlID="TextBoxTo" />
</asp:RangeExpression>
<asp:OrderByExpression DataField="ListPrice" Direction="Descending">
<asp:ThenBy DataField="ProductID" Direction="Ascending" />
</asp:OrderByExpression>
<asp:PropertyExpression>
<asp:ControlParameter ControlID="CheckBoxMakeFlag" Name="MakeFlag" />
</asp:PropertyExpression>
</asp:QueryExtender>
CustomExpression
此表达式允许您提供可在 QueryExtender
控件中使用的自定义 LINQ 表达式。因此,让我们添加一个。
<asp:QueryExtender ID="ctlMyQueryExtender"
runat="server" TargetControlID="ldsMyLinqDataSource">
<asp:SearchExpression DataFields="Name" SearchType="StartsWith">
<asp:ControlParameter ControlID="TextBoxName" />
</asp:SearchExpression>
<asp:RangeExpression DataField="ProductID"
MaxType="Inclusive" MinType="Inclusive">
<asp:ControlParameter ControlID="TextBoxFrom" />
<asp:ControlParameter ControlID="TextBoxTo" />
</asp:RangeExpression>
<asp:OrderByExpression DataField="ListPrice" Direction="Descending">
<asp:ThenBy DataField="ProductID" Direction="Ascending" />
</asp:OrderByExpression>
<asp:PropertyExpression>
<asp:ControlParameter ControlID="CheckBoxMakeFlag" Name="MakeFlag" />
</asp:PropertyExpression>
<asp:CustomExpression OnQuerying="FilterProducts"></asp:CustomExpression>
</asp:QueryExtender>
现在,在 default.aspx.cs 的代码隐藏中添加自定义方法 FilterProducts
。
protected void FilterProducts(object sender, CustomExpressionEventArgs e)
{
e.Query = from p in e.Query.Cast<Product>()
where p.ListPrice >= 6600
select p;
}
现在,让我们添加一个 GridView
控件以在网页上显示数据,并根据应用的表达式过滤我们的数据。
<asp:GridView ID="GridView1" CssClass="grd-cell-strd"
runat="server" AllowSorting="true"
AllowPaging="True" DataSourceID="ldsMyLinqDataSource"
AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="ProductID"
HeaderText="ProductID" ReadOnly="True"
SortExpression="ProductID" />
<asp:BoundField DataField="Name" HeaderText="Name" ReadOnly="True"
SortExpression="Name" />
<asp:BoundField DataField="ProductNumber" HeaderText="ProductNumber"
ReadOnly="True" SortExpression="ProductNumber" />
<asp:CheckBoxField DataField="MakeFlag"
HeaderText="MakeFlag" ReadOnly="True"
SortExpression="MakeFlag" />
<asp:CheckBoxField DataField="FinishedGoodsFlag"
HeaderText="FinishedGoodsFlag"
ReadOnly="True" SortExpression="FinishedGoodsFlag" />
<asp:BoundField DataField="Color" HeaderText="Color" ReadOnly="True"
SortExpression="Color" />
<asp:BoundField DataField="StandardCost" HeaderText="StandardCost"
ReadOnly="True" SortExpression="StandardCost" />
<asp:BoundField DataField="ListPrice"
HeaderText="ListPrice" ReadOnly="True"
SortExpression="ListPrice" />
<asp:BoundField DataField="Size"
HeaderText="Size" ReadOnly="True"
SortExpression="Size" />
<asp:BoundField DataField="Class"
HeaderText="Class" ReadOnly="True"
SortExpression="Class" />
<asp:BoundField DataField="DaysToManufacture"
HeaderText="DaysToManufacture"
ReadOnly="True" SortExpression="DaysToManufacture" />
<asp:BoundField DataField="ModifiedDate" HeaderText="ModifiedDate"
ReadOnly="True" SortExpression="ModifiedDate" />
</Columns>
</asp:GridView>
好了,就是这样。将此代码添加到您新创建的 ASPX 页面并运行!
结论
QueryExtender
控件使在网页上过滤数据更加容易。它提供了比传统的 LINQ Where 子句更丰富的过滤表达式。它还为 LinqDataSource
和 EntityDataSource
控件提供了通用的查询语言。如果您将 QueryExtender
与这些数据源控件一起使用,则可以在 Web 页面中提供搜索功能,而无需编写模型特定的 Where 子句或 eSQL 语句。此外,它还支持我们刚刚查看过的各种过滤选项,可以单独使用,也可以组合使用作为 AND 过滤器。