クエリ結果のページング (ADO.NET)

更新 : November 2007

クエリ結果のページングとは、クエリ結果をデータの小さなサブセット、つまりページに分けて返すプロセスです。クエリ結果のページングは、結果を管理しやすい小さな単位でユーザーに表示するために行われる一般的な処理です。

DataAdapter には、Fill メソッドのオーバーロードを通じて 1 ページ分のデータだけを返す機能が用意されています。しかしこれは大きなクエリ結果のページングには適していません。DataAdapter が目的の DataTable または DataSet に、要求されたレコードだけを格納する一方で、クエリ全体を返すためのリソースが使用されるためです。クエリ全体を返す必要があるリソースを使用せずにデータ ソースから 1 ページ分のデータを返すには、必要な行だけ返すように限定する抽出条件をクエリに追加します。

Fill メソッドを使用して 1 ページ分のデータを返すには、データ ページの先頭レコードを指定する startRecord パラメータおよびデータ ページのレコード数を指定する maxRecords パラメータを指定します。

Fill メソッドを使用してクエリ結果の最初のページ (ページ サイズ : 5 つのレコード) を返す方法を次のコード サンプルに示します。

Dim currentIndex As Integer = 0
Dim pageSize As Integer = 5

Dim orderSQL As String = "SELECT * FROM dbo.Orders ORDER BY OrderID"
' Assumes that connection is a valid SqlConnection object.
Dim adapter As SqlDataAdapter = _
  New SqlDataAdapter(orderSQL, connection)

Dim dataSet As DataSet = New DataSet()
adapter.Fill(dataSet, currentIndex, pageSize, "Orders")
int currentIndex = 0;
int pageSize = 5;

string orderSQL = "SELECT * FROM Orders ORDER BY OrderID";
// Assumes that connection is a valid SqlConnection object.
SqlDataAdapter adapter = new SqlDataAdapter(orderSQL, connection);

DataSet dataSet = new DataSet();
adapter.Fill(dataSet, currentIndex, pageSize, "Orders");

上記の例では、DataSet に 5 つのレコードだけが格納されますが、Orders テーブル全体が返されます。DataSet にこれと同じ 5 つのレコードを格納し、5 つのレコードだけを返すには、次のコード サンプルに示すように SQL ステートメントで TOP 句と WHERE 句を使用します。

Dim pageSize As Integer = 5

Dim orderSQL As String = "SELECT TOP " & pageSize & _
  " * FROM Orders ORDER BY OrderID"
Dim adapter As SqlDataAdapter = _
  New SqlDataAdapter(orderSQL, connection)

Dim dataSet As DataSet = New DataSet()
adapter.Fill(dataSet, "Orders") 
int pageSize = 5;

string orderSQL = "SELECT TOP " + pageSize + 
  " * FROM Orders ORDER BY OrderID";
SqlDataAdapter adapter = new SqlDataAdapter(orderSQL, connection);

DataSet dataSet = new DataSet();
adapter.Fill(dataSet, "Orders");

この方法でクエリ結果をページングするときは、次のレコード ページを返すコマンドに一意の ID を渡すために、行を順序付けする固有の識別子を保存する必要があります。次のコード サンプルで示します。

Dim lastRecord As String = _
  dataSet.Tables("Orders").Rows(pageSize - 1)("OrderID").ToString()
string lastRecord = 
  dataSet.Tables["Orders"].Rows[pageSize - 1]["OrderID"].ToString();

startRecord パラメータおよび maxRecords パラメータを受け取る Fill メソッドのオーバーロードを使用して次のレコード ページを返すには、現在のレコード インデックスをページ サイズの分だけインクリメントし、テーブルにレコード ページを格納します。DataSet に 1 ページ分のレコードだけを追加する場合でも、データベース サーバーはクエリ結果全体を返すことに注意してください。次のデータ ページを格納する前にテーブル行をクリアするコード サンプルを次に示します。データベース サーバーとのやり取りを減らすために、ローカルのキャッシュに、返された一定数の行を保存することもできます。

currentIndex = currentIndex + pageSize

dataSet.Tables("Orders").Rows.Clear()

adapter.Fill(dataSet, currentIndex, pageSize, "Orders")
currentIndex += pageSize;

dataSet.Tables["Orders"].Rows.Clear();

adapter.Fill(dataSet, currentIndex, pageSize, "Orders");

データベース サーバーによってクエリ全体を返さずに次のレコード ページを返すには、SELECT ステートメントに限定的な抽出条件を指定します。上の例では最後に返されたレコードが保存されますが、次のコード サンプルに示すようにそのレコードを WHERE 句で使用するとクエリの開始点を指定できます。

orderSQL = "SELECT TOP " & pageSize & _
  " * FROM Orders WHERE OrderID > " & lastRecord & " ORDER BY OrderID"
adapter.SelectCommand.CommandText = orderSQL

dataSet.Tables("Orders").Rows.Clear()

adapter.Fill(dataSet, "Orders")
orderSQL = "SELECT TOP " + pageSize + 
  " * FROM Orders WHERE OrderID > " + lastRecord + " ORDER BY OrderID";
adapter.SelectCommand.CommandText = orderSQL;

dataSet.Tables["Orders"].Rows.Clear();

adapter.Fill(dataSet, "Orders");

参照

その他の技術情報

DataAdapter と DataReader (ADO.NET)