GridViewのページングでAllowPagingをTrueにするだけだと全ページ分のデータをとっているので、データ量が多いページではパフォーマンスが悪化してしまう。
ASP.NET 3.5以上だとVirtualItemCountという便利なプロパティがあって楽にやれそう。
ASP.NET 2.0だとこれがないので、ObjectDataSourceを使って下記のように工夫必要がある。
GridViewのページング機能を有効にする
10行目のAllowPagingをTrueにし、ページングを有効にする。
Paging.aspx
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Paging.aspx.vb" Inherits="Paging" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Paging Test</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="MyGridView" runat="server" AllowPaging="True" >
</asp:GridView>
</div>
</form>
</body>
</html>
GridViewのDataSourceへObjectDataSourceをセット
ObjectDataSourceを生成し、25から29行目でデータを抽出するクラス、メソッド、メソッドの引数名を設定する。
25行目で設定したオブジェクトを36行目で生成する。
Paging.aspx.vb
Imports System.Data
Partial Class Paging
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
BindGrid()
End If
End Sub
Protected Sub GridView1_PageIndexChanging(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewPageEventArgs) Handles MyGridView.PageIndexChanging
MyGridView.PageIndex = e.NewPageIndex
BindGrid()
End Sub
Private Sub BindGrid()
MyGridView.DataSource = CreateDataSource()
MyGridView.DataBind()
End Sub
Private Function CreateDataSource() As ObjectDataSource
Dim ods = New ObjectDataSource()
ods.EnablePaging = MyGridView.AllowPaging
ods.TypeName = "PagingService"
ods.SelectMethod = "GetData"
ods.SelectCountMethod = "GetDataCount"
ods.StartRowIndexParameterName = "startRow"
ods.MaximumRowsParameterName = "maxRows"
ods.EnableViewState = False
AddHandler ods.ObjectCreating, New ObjectDataSourceObjectEventHandler(AddressOf CreateDataObject)
Return ods
End Function
Private Sub CreateDataObject(ByVal sender As Object, ByVal e As ObjectDataSourceEventArgs)
e.ObjectInstance = New PagingService()
End Sub
End Class
データ抽出ロジック(テスト実装)
バインド時にGetDataメソッドやGetDataCountメソッドが呼び出される。
GetDataメソッドは1ページに必要なデータを抽出して返す。
ObjectDataSourceから渡されるstartRow変数やmaxRows変数を抽出条件に利用できる。
MySQLではLIMITで、OracleではROWNUMやROW_NUMBERを条件に抽出できる。
GetDataCountメソッドは全件数をカウントして返す。
PagingService.vb
Imports Microsoft.VisualBasic
Imports System.Data
Public Class PagingService
Public Function GetData(ByVal startRow As Integer, ByVal maxRows As Integer) As DataTable
Dim dt As DataTable = New DataTable()
Dim dr As DataRow
dt.Columns.Add(New DataColumn("IntegerValue", GetType(Int32)))
dt.Columns.Add(New DataColumn("StringValue", GetType(String)))
dt.Columns.Add(New DataColumn("DateTimeValue", GetType(String)))
dt.Columns.Add(New DataColumn("BoolValue", GetType(Boolean)))
Dim i As Integer
For i = startRow To ((startRow + maxRows) - 1)
dr = dt.NewRow()
dr(0) = i
dr(1) = "Item " & i.ToString()
dr(2) = DateTime.Now.ToShortDateString()
If (i Mod 2 <> 0) Then
dr(3) = True
Else
dr(3) = False
End If
dt.Rows.Add(dr)
Next i
Return dt
End Function
Public Function GetDataCount() As Integer
Return 1000
End Function
End Class