SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

ASP.NET 2.0とSQL Server 2005によるカスタムのページング処理

結果を順序付けする機能によるサブセット取得の簡易化

  • X ポスト
  • このエントリーをはてなブックマークに追加

SQL Server 2005で1ページ分のデータを効率よく返す

 4Guysへの以前の投稿『Returning Ranked Results with Microsoft SQL Server 2005』で紹介したように、SQL Server 2005では、順序付けした結果を返す新しいキーワードがいくつか導入されました。特に、ROW_NUMBER()キーワードを指定すると、返される結果に連番の行番号が付けられます。そこで、ROW_NUMBER()を使って、次のようなクエリを実行することで特定のページのデータを取得することができます。

SELECT ...
FROM
   (SELECT ...
         ''ROW_NUMBER() OVER(ORDER BY ColumnName) as RowNum''
    FROM Employees e
   ) as <DerivedTableName>
WHERE ''RowNum BETWEEN @startRowIndex AND (@startRowIndex + @maximumRows) - 1''

 ここで、@startRowIndexは開始行のインデックスで、@maximumRowsはページあたりの表示レコードの最大数です。このクエリは、開始行のインデックスから「開始行のインデックス+ページあたりのレコード数」のインデックスまでのROW_NUMBER()を持つレコードのサブセットを返します。

 この概念を理解するために、具体的な例を紹介しましょう。ここに、5,000個のレコードから成る「Employees」テーブルがあるとします(事業が好調ですね)。次のクエリを実行します。

SELECT RowNum, EmployeeID, LastName, FirstName
FROM
   (SELECT EmployeeID, LastName, FirstName
       ''ROW_NUMBER() OVER(ORDER BY EmployeeID) as RowNum''
    FROM Employees e
   ) as EmployeeInfo

 この場合は、次のような結果が返されます。

RowNumEmployeeIDLastNameFirstName
11000SmithFrank
21001JacksonLucy
31011LeeSam
41012MitchellJisun
51013YatesScott
61016PropsKathryn
……
50006141JordanDJ

 EmployeeIDフィールドが連番ではなく、しかも1から始まっていない場合でも、ROW_NUMBER()値は1つ目のレコードに対する1から始まり、連番になっていることに注意してください。そのため、ページあたりのレコード数を10個として、3ページ目を表示する場合は、31~40のレコードが必要であることが分かるので、簡単なWHERE句でそれを実現することができます。

カスタムのページング処理に合わせてObjectDataSourceを設定する

 既に説明したように、SqlDataSourceはカスタムの並べ替え機能に向いていませんが、ObjectDataSourceはこの機能をサポートするように作られています。ObjectDataSourceは、オブジェクトの提供データにアクセスするためのデータソースコントロールです。データ提供側のオブジェクトは、自身が提供するデータをさまざまな手段で取得することができます(Webサービス、データベース、ファイルシステム、XMLファイルなど、多様な方法が考えられます)。ObjectDataSourceは、オブジェクトがどのような手段でデータを取得しているかに関係なく、ただオブジェクトとそのデータを使用するデータWebコントロール(GridViewコントロールなど)との間のプロキシの役割を果たします(ObjectDataSourceの詳細については、『ObjectDataSourceコントロールの概要』を参照してください)。

 データWebコントロールをObjectDataSourceにバインドする場合には[ページングを有効にする]チェックボックスをオンにします。このとき、特にカスタムのページング処理をサポートするようにObjectDataSourceを設定していないと、既定のページング処理が有効になります。カスタムのページング処理をサポートするようにObjectDataSourceを設定するには、次の機能を提供するオブジェクトを使う必要があります。

  1. 最後の2つの入力パラメータとして2つの整数値を取るメソッド。1つ目の整数値ではデータの取得先の開始インデックス(ゼロベース)を指定し、2つ目の整数値ではページあたりに取得するレコードの最大数を指定します。このメソッドは、要求されているデータの正しいサブセット、つまり指定されたインデックスを先頭として、指定されたレコードの合計数を超えないデータを返す必要があります。
  2. ページング処理の対象となるレコードの合計数を表す整数値を返すメソッド(ページ番号を表示するときや[次のページ]リンクを有効にするかどうかを指定するときにはデータの総ページ数を認識する必要があるので、ページング処理コントロールのレンダリング時にデータWebコントロールでこの情報が使用されます)。

 これらの機能を提供するベースオブジェクトを用いれば、カスタムのページング処理をサポートするようにObjectDataSourceを設定することは非常に簡単です。必要なのは、次に示すObjectDataSourceのプロパティを設定することだけです。

  • EnablePagingプロパティをTrueに設定する。
  • SelectMethodプロパティを、開始インデックスと最大行数を入力パラメータとして受け取るメソッドに設定する。
  • StartRowIndexParameterNameプロパティを、SelectMethodメソッドの開始インデックスを受け取る整数型入力パラメータの名前に設定する。この値を省略すると、既定でstartRowIndexが設定される。
  • MaximumRowsParameterNameプロパティを、SelectMethodメソッドの最大行数を受け取るの整数型入力パラメータの名前に設定する。この値を省略すると、既定でmaximumRowsが設定される。
  • SelectCountMethodプロパティを、ページング処理対象のレコードの合計数を返すメソッドに設定する。

 これだけです。この設定が終わると、ObjectDataSourceはカスタムのページング処理機能を使うようになります。もちろん、ここでの山場は、データの正しいサブセットを賢く取得する基となるオブジェクトの作成です。しかし、そのオブジェクトを作成してしまえば、後はいくつかのプロパティを設定するだけです。

カスタムのページング処理をサポートするオブジェクトを作成する

 ObjectDataSourceをGridViewにバインドするためには、まずObjectDataSourceが使う基となるオブジェクトが必要であり、このオブジェクトには、データの特定のサブセットにアクセスしてページング処理の対象となる行数を返すメソッドが必要です。Joseph Chancellorの記事『Using Strongly-Typed Data Access in Visual Studio 2005 and ASP.NET 2.0』とBrian Noyesの記事『Build a Data Access Layer with the Visual Studio 2005 DataSet Designer』で述べられているように、Visual Studio 2005ではObjectDataSourceに接続できるオブジェクトを簡単に作成できます。まず、これらのオブジェクトのメソッドから返される厳密に型指定されたDataSet(Strongly-typed DataSet)にデータを取り込む場合に使うストアドプロシージャ(またはSQLクエリ)を定義します。

 本稿のサンプルファイルには、50,000人分の社員レコード(および、追加レコードをまとめて追加できる簡単な方法)から成るサンプルデータベースが収められています。このデータベースに、カスタムのページング処理の2つのデモで使う次の3つのストアドプロシージャが含まれています。

  • GetEmployeesSubset(@startRowIndex int, @maximumRows int)
  • EmployeeID順に並べ替えて、@startRowIndexから始まる最大@maximumRows個のレコードを「Employees」テーブルから返します。
  • GetEmployeesRowCount
  • 「Employees」テーブル内のレコードの合計数を返します。
  • GetEmployeesSubsetSorted(@sortExpression nvarchar(50), @startRowIndex int, @maximumRows int)
  • 指定の並べ替え式(@sortExpression)に基づいて並べ替えられた1ページ分のデータを返します。このストアドプロシージャでは、例えば給与順に並べ替えられた1ページ分のデータを返すことができます(GetEmployeesSubsetは常にEmployeeID順に並べ替えられたレコードを返します)。カスタムのページング処理と並べ替えを併用するGridViewを作成する場合にはこの柔軟性が必要です。
 本稿ではカスタムのページング処理と並べ替えを併用するGridViewの実装方法については説明しませんが、例はサンプルファイルに入っています。カスタムのページング処理と双方向の並べ替えを併用するUIの作成方法については、『ASP.NET 2.0でカスタムのページング処理と並び替えを併用する』を参照してください。

 これらのストアドプロシージャを作成した後、型指定されたDataSetをプロジェクト(Employees.xsd)に追加して、基となるオブジェクトを作成しました。次に、前述の各ストアドプロシージャに対して1つずつ、合計3つのメソッドを追加しました。これで、ObjectDataSourceのプロパティに接続できるGetEmployeesSubset(startRowIndex、maximumRows)メソッドおよびGetEmployeesRowCount()メソッドを持つEmployeesTableAdapterオブジェクトが出来上がりました(型指定されたDataSetの作成手順については、『Using Strongly-Typed Data Access in Visual Studio 2005 and ASP.NET 2.0』とScott Guthrieのブログの『Building a DAL using Strongly Typed TableAdapters and DataTables in VS 2005 and ASP.NET 2.0』を参照してください)。

次のページ
既定のページング処理とカスタムのページング処理のパフォーマンスを比較する

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Scott Mitchell(Scott Mitchell)

http://www.4guysfromrolla.com/ScottMitchell.shtml

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/430 2006/08/22 15:49

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング