QueryExtenderコントロール
QueryExtenderコントロールは、簡単に言ってしまうとLinqDataSourceコントロールとEntityDataSourceコントロールで取得されたデータにフィルタをかけるコントロールです。このコントロールの魅力は大きく分けて2つになります。
- 宣言型のコーディングのみでデータのフィルタリングが簡単にできる点
- サーバーサイドでLINQによるフィルタリングが行われるという点
つまり、開発者にとっては開発生産性が高く、ユーザーにとっては最適化されたデータのみ返される便利なコントロールです(図8~9)。
多くのフィルタクラスをサポートしているQueryExtenderコントロールですが、活用頻度の高くなりそうなクラスをいくつかピックアップして紹介します。
クラス名 | 概要 |
CustomExpression | ユーザーが定義したフィルタを適用。カスタム式は関数で作成し、OnQueryingプロパティを使い呼び出し可能 |
OrderByExpression | OrderBy句をデータソースに適用 |
PropertyExpression | 指定した値をデータソースと比較し、フィルタを適用 |
RangeExpression | 指定した値以上か以下か、もしくはその間にあるかどうかを指定 |
SearchExpression | 指定されたフィールド内で、指定された文字列を検索 |
続いて各フィルタクラスの基本的な宣言例を記述します。
<asp:○○○Expression DataFields="フィルタを適用させたいデータフィールド" 各Expression専用プロパティ="XXX"> <asp:ControlParameter ControlID="フィルタのパラメータの値を取得するサーバーコントロールID" /> </asp:○○○Expression>
各フィルタクラスでは、データフィールドの指定と、そのフィルタクラスが持つプロパティを設定します。そして、そのフィルタのパラメータの値を取得するサーバーコントロールを<asp:ControlParameter />タグで設定します。
それでは実際のサンプルです。サンプルではSearchExpresison/RangeExpression/OrderByExpressionクラスを使用した例を記述します。
<%--EndityDataSouorce1(titlesエンティティ)をテーブルタグにバインドして表示--%> <asp:ListView ID="ListView1" runat="server" DataSourceID="EntityDataSource1"> <LayoutTemplate> <table> <thead> <tr> <th>title_id</th> <th>title1</th> <th>type</th> <th>price</th> </tr> </thead> <tbody> <asp:PlaceHolder runat="server" ID="itemPlaceholder" /> </tbody> </table> </LayoutTemplate> <ItemTemplate> <tr> <td><%# Eval("title_id")%></td> <td><%# Eval("title1")%></td> <td><%# Eval("type")%></td> <td><%# Eval("price")%></td> </tr> </ItemTemplate> </asp:ListView> <%--PubsEDMから、titlesエンティティを抽出--%> <asp:EntityDataSource ID="EntityDataSource1" runat="server" ConnectionString="name=PUBSEntities" DefaultContainerName="PUBSEntities" EnableFlattening="False" EntitySetName="titles"> </asp:EntityDataSource> <%--各種フィルタクラスの設定を行う--%> <asp:QueryExtender ID="QueryExtender1" TargetControlID="EntityDataSource1" runat="server"> <%--txttitleに入力された値が、title1列の項目に含まれているかどうか検索を行う--%> <asp:SearchExpression DataFields="title1" SearchType="Contains"> <asp:ControlParameter ControlID="txttitle" /> </asp:SearchExpression> <%--txttypeに入力された値が、type列の項目に含まれているかどうか検索を行う--%> <asp:SearchExpression DataFields="type" SearchType="Contains"> <asp:ControlParameter ControlID="txttype" /> </asp:SearchExpression> <%--txtmin/txtmaxに入力された数値を元にprice列のフィルタリングを行う--%> <asp:RangeExpression DataField="price" MinType="Inclusive" MaxType="Inclusive"> <asp:ControlParameter ControlID="txtmin" /> <asp:ControlParameter ControlID="txtmax" /> </asp:RangeExpression> <%--title1列に対して昇順でデータを表示する--%> <asp:OrderByExpression DataField="title1" Direction="Ascending" /> </asp:QueryExtender> <br /> title1内で次の項目を検索:<asp:TextBox ID="txttitle" runat="server"></asp:TextBox><br /> type内で次の項目を検索:<asp:TextBox ID="txttype" runat="server"></asp:TextBox><br /> price下限値:<asp:TextBox ID="txtmin" runat="server"></asp:TextBox><br /> price上限値:<asp:TextBox ID="txtmax" runat="server"></asp:TextBox><br /> <asp:Button ID="Button2" runat="server" Text="再検索" />
上記のみで前述の図8~9の実行結果が確認できます。コードビハインドの記述を行わずともフィルタリングができるようになります。QueryExtender以外の各種サーバーコントロールは、特筆すべき点はありません。EntityDataSourceコントロールでPubsデータベースのtitlesエンティティを抽出し、ListViewコントロールにバインドしているだけです。各種フィルタリング設定はQueryExtenderコントロールで行われています。
SearchExpressionタグ内の属性で、title1/type列に対して文字列検索を行う宣言(SearchTypeのContains設定)を記述し、検索を行うパラメタとしてtxttitle/txttypeテキストボックスに入力された値を設定しています。
RangeExpressionタグ内の属性で、price列に対して数値比較を行う際に入力された値と同等の値もフィルタ結果として残す宣言を記述し(MinType/MaxTypeのInclusive設定)、txtmin/txtmaxテキストボックスに入力された数値に対してフィルタリングを行う設定をしています。
OrderByExpressionタグ内の属性で、title1列に対して昇順でデータを表示する宣言を記述し、実行時に昇順でデータが表示されるように設定しています。
ご覧の通り、QueryExtenderコントロールの設定をするだけで、ユーザーが自分の意思でフィルタリングを行い欲しい情報を抽出できるようになります。