10.3 QueryExtender控件

QueryExtender控件是ASP.NET 4新增加的一个数据筛选控件,它用于为从数据源检索的数据创建筛选器,并且在数据源中不使用显式Where子句。可以将它添加到EntityDataSource控件或LinqDataSource控件以筛选这些控件返回的数据。它依赖于LINQ,但无须了解如何编写LINQ查询即可使用该查询扩展程序。利用它,可以简单地通过声明性语法筛选网页标记中的数据。除此之外,它还支持ASP.NET动态数据专用的表达式。

QueryExtender控件支持多种可用于筛选数据的选项,即支持搜索字符串、搜索指定范围内的值、将表中的属性值与指定的值进行比较、排序和自定义查询等。下面就来详细阐述如何使用它进行数据筛选。

10.3.1 SearchExpession

SearchExpression类将一个或多个字段中的指定字符串与提供的值作比较,它执行“开头为”、“包含”或“结尾为”搜索。例如,可以向文本框控件中输入文本,并使用该表达式搜索从数据源控件返回的列中的该文本。

在使用SearchExpression时,必须为它的SearchType属性和DataFields属性指定值,以指明要执行的搜索类型以及要搜索的数据字段。其中,SearchType属性使用的SearchType枚举包含要在SearchExpression类的实例中使用的搜索类型。枚举值为:

❑StartsWith:指示的字段中的任意位置开始的搜索。

❑Contains:指示从一个字段开头开始的搜索。

❑EndsWith:指示在字段结尾的搜索。

因为QueryExtender控件依赖于LINQ。所以要在QueryExtender控件中使用SearchExpression进行数据搜索,还需要创建一个.dbml文件。创建的示例Employees.dbml文件如图10-21所示。

创建好Employees.dbml文件之后,就可以通过在页面中使用ASP.NET控件来提供要搜索的值。为此,还需要将SearchExpression对象中ControlParameter类的ControlID属性设置为该ASP.NET控件的ID。

figure_0397_0294

图 10-21 示例Employees.dbml文件

下面的示例程序演示了如何在ASP.NET 4数据库的Employee数据表的EmployeeName列中,搜索以SearchTextBox控件中指定的字符串开头的员工信息。从LinqDataSource控件返回的结果显示在GridView控件中,如代码清单10-3所示。

代码清单10-3 SearchExpressionTest.aspx


<form id="form1"runat="server">

搜索员工姓名:

<asp:TextBox ID="SearchTextBox"runat="server"/>

<asp:Button ID="Button1"runat="server"Text="搜索"/>

<br/><br/>

<asp:LinqDataSource ID="LinqDataSource1"

TableName="Employees"runat="server"

ContextTypeName="_10_2.EmployeesDataContext"

EntityTypeName=""Select="new(employeeid, employeename,

department, address, email, workdate)">

</asp:LinqDataSource>

<asp:QueryExtender ID="QueryExtender1"runat="server"

TargetControlID="LinqDataSource1">

<asp:SearchExpression SearchType="StartsWith"

DataFields="EmployeeName">

<asp:ControlParameter ControlID="SearchTextBox"/>

</asp:SearchExpression>

</asp:QueryExtender>

<asp:GridView ID="GridView1"runat="server"Width="100%"

DataSourceID="LinqDataSource1"AllowPaging="True"

AutoGenerateColumns="False"DataKeyNames="employeeid">

<Columns>

<asp:BoundField DataField="employeeid"HeaderText="编号"

ReadOnly="True"SortExpression="employeeid"/>

<asp:BoundField DataField="employeename"HeaderText="姓名"

SortExpression="employeename"/>

<asp:BoundField DataField="department"HeaderText="部门"

SortExpression="department"/>

<asp:BoundField DataField="address"HeaderText="住址"

SortExpression="address"/>

<asp:BoundField DataField="email"HeaderText="邮箱"

SortExpression="email"/>

<asp:BoundField DataField="workdate"HeaderText="工作时间"

SortExpression="workdate"/>

</Columns>

</asp:GridView>

</form>


示例运行结果如图10-22所示。

figure_0398_0295

图 10-22 示例运行结果

还需要说明的是,如果在QueryExtender控件中使用的LINQ提供程序支持区分大小写,还可以使用SearchExpression的ComparisonType属性启用或禁用区分大小写。

10.3.2 RangeExpression

RangeExpression类与SearchExpression类相似,不同之处在于RangeExpression类使用了一对值来定义范围,以确定列中的值是否在指定的最小值和最大值之间。例如,可以在表的“单价”列中搜索介于10元和100元之间的值。

在使用RangeExpression时,必须使用DataField属性指定要搜索的列;使用MinType属性指定是否在搜索结果中包括或排除最小值;使用MaxType属性指定是否包括或排除最大值。其中,MinType与MaxType属性的值包括Inclusive、Exclusive和None。当MinType属性或MaxType属性设置为Inclusive时,范围的最大值和最小值包括在搜索结果中,这相当于执行一个>=或<=运算;Exclusive字段等效于>或<运算;None将不会对范围施加任何限制。最大值和最小值可以通过在页面中使用ASP.NET控件来指定,然后将该值作为ControlParameter控件中的参数传递到QueryExtender控件。

下面的示例程序演示了如何在ASP.NET 4数据库的Employee数据表的EmployeeID列中,搜索员工编号位于FromTextBox和ToTextBox文本框指定的范围内的员工信息。其中,筛选器包括最小值,但不包括结果中的最大值。最后,从LinqDataSource控件返回的结果显示在GridView控件中,如代码清单10-4所示。

代码清单10-4 RangeExpressionTest.aspx


<form id="form1"runat="server">

搜索员工编号:

<asp:TextBox ID="FromTextBox"runat="server"></asp:TextBox>

<asp:TextBox ID="ToTextBox"runat="server"></asp:TextBox>

<asp:Button ID="Button1"runat="server"Text="搜索"/>

<br/>

<br/>

<asp:LinqDataSource ID="LinqDataSource1"

TableName="Employees"runat="server"

ContextTypeName="_10_2.EmployeesDataContext"

EntityTypeName=""Select="new(employeeid, employeename,

department, address, email, workdate)">

</asp:LinqDataSource>

<asp:QueryExtender ID="QueryExtender1"runat="server"

TargetControlID="LinqDataSource1">

<asp:RangeExpression DataField="employeeid"

MinType="Inclusive"MaxType="Exclusive">

<asp:ControlParameter ControlID="FromTextBox"/>

<asp:ControlParameter ControlID="ToTextBox"/>

</asp:RangeExpression>

</asp:QueryExtender>

<asp:GridView ID="GridView1"runat="server"Width="100%"

DataSourceID="LinqDataSource1"

AllowPaging="True"AutoGenerateColumns="False"

DataKeyNames="employeeid">

<Columns>

<asp:BoundField DataField="employeeid"HeaderText="编号"

ReadOnly="True"SortExpression="employeeid"/>

<asp:BoundField DataField="employeename"HeaderText="姓名"

SortExpression="employeename"/>

<asp:BoundField DataField="department"HeaderText="部门"

SortExpression="department"/>

<asp:BoundField DataField="address"HeaderText="住址"

SortExpression="address"/>

<asp:BoundField DataField="email"HeaderText="邮箱"

SortExpression="email"/>

<asp:BoundField DataField="workdate"HeaderText="工作时间"

SortExpression="workdate"/>

</Columns>

</asp:GridView>

</form>


示例运行结果如图10-23所示。

figure_0399_0296

图 10-23 示例运行结果

10.3.3 PropertyExpression

相对于其他表达式类,Pro perty-Expression类比较简单,它将列的属性值与指定的值进行比较。它为每个参数的值和IQueryable数据对象的相应属性创建一个相等(==)比较。如果提供多个参数,将使用逻辑AND运算符组合这些参数,包含空值的参数不添加到Where子句中。

下面的示例程序演示了如何在ASP.NET 4数据库的Employee数据表的EmployeeName列中,搜索员工姓名等于SearchTextBox文本框中指定的值的员工信息。从LinqDataSource控件返回的结果显示在GridView控件中,如代码清单10-5所示。

代码清单10-5 PropertyExpressionTest.aspx


<form id="form1"runat="server">

搜索员工姓名:

<asp:TextBox ID="SearchTextBox"runat="server"/>

<asp:Button ID="Button1"runat="server"Text="搜索"/>

<br/>

<br/>

<asp:LinqDataSource ID="LinqDataSource1"

TableName="Employees"runat="server"

ContextTypeName="_10_2.EmployeesDataContext"

EntityTypeName=""Select="new(employeeid, employeename,

department, address, email, workdate)">

</asp:LinqDataSource>

<asp:QueryExtender ID="QueryExtender1"runat="server"

TargetControlID="LinqDataSource1">

<asp:PropertyExpression>

<asp:ControlParameter ControlID="SearchTextBox"

Name="employeename"/>

</asp:PropertyExpression>

</asp:QueryExtender>

<asp:GridView ID="GridView1"runat="server"Width="100%"

DataSourceID="LinqDataSource1"

AllowPaging="True"AutoGenerateColumns="False"

DataKeyNames="employeeid">

<Columns>

<asp:BoundField DataField="employeeid"HeaderText="编号"

ReadOnly="True"SortExpression="employeeid"/>

<asp:BoundField DataField="employeename"HeaderText="姓名"

SortExpression="employeename"/>

<asp:BoundField DataField="department"HeaderText="部门"

SortExpression="department"/>

<asp:BoundField DataField="address"HeaderText="住址"

SortExpression="address"/>

<asp:BoundField DataField="email"HeaderText="邮箱"

SortExpression="email"/>

<asp:BoundField DataField="workdate"HeaderText="工作时间"

SortExpression="workdate"/>

</Columns>

</asp:GridView>

</form>


示例运行结果如图10-24所示。

figure_0400_0297

图 10-24 示例运行结果

10.3.4 OrderByExpression

前面讲过,QueryExtender控件支持多种可用于筛选数据的选项。但在使用筛选器选项之后,还可以使用OrderByExpression对象来排序数据。其中,OrderByExpression类可以按指定列和排序方向对数据进行排序。

在使用OrderByExpression时,可以使用它的DataField属性指定要排序的数据字段;使用Direction属性指定排序方向。OrderByExpression对象应用到数据源后,还可以使用ThenBy表达式对另一个数据字段执行后续排序。

下面的示例程序演示了如何在ASP.NET 4数据库的Employee数据表的Department列中,搜索员工部门等于SearchTextBox文本框中指定的字符串开头的员工信息。其中,OrderByExpression对象按Workdate数据字段的降序和EmployeeID字段的升序对数据排序。最后从LinqDataSource控件返回的结果显示在GridView控件中。如代码清单10-6所示。

代码清单10-6 OrderByExpressionTest.aspx


<form id="form1"runat="server">

搜索员工部门:

<asp:TextBox ID="SearchTextBox"runat="server"/>

<asp:Button ID="Button1"runat="server"Text="搜索"/>

<br/>

<br/>

<asp:LinqDataSource ID="LinqDataSource1"TableName="Employees"

runat="server"ContextTypeName="_10_2.EmployeesDataContext"

EntityTypeName=""Select="new(employeeid, employeename,

department, address, email, workdate)">

</asp:LinqDataSource>

<asp:QueryExtender ID="QueryExtender1"runat="server"

TargetControlID="LinqDataSource1">

<asp:SearchExpression SearchType="StartsWith"

DataFields="department">

<asp:ControlParameter ControlID="SearchTextBox"/>

</asp:SearchExpression>

<asp:OrderByExpression DataField="workdate"

Direction="Descending">

<asp:ThenBy DataField="employeeid"

Direction="Ascending"/>

</asp:OrderByExpression>

</asp:QueryExtender>

<asp:GridView ID="GridView1"runat="server"Width="100%"

DataSourceID="LinqDataSource1"

AllowPaging="True"AutoGenerateColumns="False"

DataKeyNames="employeeid">

<Columns>

<asp:BoundField DataField="employeeid"HeaderText="编号"

ReadOnly="True"SortExpression="employeeid"/>

<asp:BoundField DataField="employeename"HeaderText="姓名"

SortExpression="employeename"/>

<asp:BoundField DataField="department"HeaderText="部门"

SortExpression="department"/>

<asp:BoundField DataField="address"HeaderText="住址"

SortExpression="address"/>

<asp:BoundField DataField="email"HeaderText="邮箱"

SortExpression="email"/>

<asp:BoundField DataField="workdate"HeaderText="工作时间"

SortExpression="workdate"/>

</Columns>

</asp:GridView>

</form>


示例运行结果如图10-25所示。

figure_0402_0298

图 10-25 示例运行结果

10.3.5 CustomExpression

如果上面的表达式类都不能够满足要求,那么可以通过CustomExpression类来提供可用于QueryExtender控件中的自定义LINQ表达式。CustomExpression类使你能够在应用程序中指定自定义表达式,然后在事件处理程序中调用它。

下面的示例演示了如何创建一个由QueryExtender控件使用的CustomExpression对象。其中,该自定义表达式调用包含自定义LINQ表达式的QueryEmployees方法。筛选操作的结果显示在GridView控件中,如代码清单10-7所示。

代码清单10-7 CustomExpressionTest.aspx


<form id="form1"runat="server">

<asp:LinqDataSource ID="LinqDataSource1"

TableName="Employees"runat="server"

ContextTypeName="_10_2.EmployeesDataContext"

EntityTypeName=""Select="new(employeeid, employeename,

department, address, email, workdate)">

</asp:LinqDataSource>

<asp:QueryExtender ID="QueryExtender1"runat="server"

TargetControlID="LinqDataSource1">

<asp:CustomExpression OnQuerying="QueryEmployees">

</asp:CustomExpression>

</asp:QueryExtender>

<asp:GridView ID="GridView1"runat="server"Width="100%"

DataSourceID="LinqDataSource1"

AllowPaging="True"AutoGenerateColumns="False"

DataKeyNames="employeeid">

<Columns>

<asp:BoundField DataField="employeeid"HeaderText="编号"

ReadOnly="True"SortExpression="employeeid"/>

<asp:BoundField DataField="employeename"HeaderText="姓名"

SortExpression="employeename"/>

<asp:BoundField DataField="department"HeaderText="部门"

SortExpression="department"/>

<asp:BoundField DataField="address"HeaderText="住址"

SortExpression="address"/>

<asp:BoundField DataField="email"HeaderText="邮箱"

SortExpression="email"/>

<asp:BoundField DataField="workdate"HeaderText="工作时间"

SortExpression="workdate"/>

</Columns>

</asp:GridView>

</form>


在上面的代码中,通过CustomExpression对象的OnQuerying属性指定了自定义LINQ表达式的QueryEmployees方法。其中,后台的自定义LINQ查询的事件处理程序QueryEmployees代码如下所示:


protected void QueryEmployees(object sender,

CustomExpressionEventArgs e)

{

e.Query=frompin e.Query.Cast<Employee>()

where p.employeeid>=5

select p;

}


示例运行结果如图10-26所示。

figure_0403_0299

图 10-26 示例运行结果