PowerTools SPREAD for ASP.NET 8.0J > 開発者の手引き > 状態管理 > 個々のページ要求に対してデータをロード |
個々のページ要求に対してデータをロードする場合は、状態を維持するのではなく、要求されるたびに個々のページを再作成することになります。
個々のページ要求に対してデータをロードする方法は、データセットの規模が大きく、サーバー資源の使用を最小限にとどめたい場合に有効です。
個々のページ要求に対してデータをロードする利点は次のとおりです。
個々のページ要求に対してデータをロードする欠点は次のとおりです。
ページが要求されるたびにデータをロードするには、SheetView クラスのIsTrackingViewState プロパティをfalseに設定します。
サンプル1
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load 'strcon変数に適切な接続文字列を設定してください。 Dim strcon As String = ConfigurationManager.ConnectionStrings("NorthwindConnectionString").ConnectionString Dim conn As New Data.SqlClient.SqlConnection(strcon) Dim adapt As Data.SqlClient.SqlDataAdapter Dim cmdText As String = "SELECT OrderID, CustomerID, EmployeeID, OrderDate, RequiredDate FROM Orders" Dim ds As New Data.DataSet() adapt = New Data.SqlClient.SqlDataAdapter(cmdText, conn) conn.Open() adapt.Fill(ds, "Orders") conn.Close() FpSpread1.Sheets(0).DataSource = ds '一次キーを指定し、ReadOnlyに設定 FpSpread1.Sheets(0).DataKeyField = "OrderID" FpSpread1.Sheets(0).Columns(0).Locked = True FpSpread1.Sheets(0).IsTrackingViewState = False End Sub Private Sub FpSpread1_UpdateCommand(ByVal sender As System.Object, ByVal e As FarPoint.Web.Spread.SpreadCommandEventArgs) Handles FpSpread1.UpdateCommand 'strcon変数に適切な接続文字列を設定してください。 Dim strcon As String = ConfigurationManager.ConnectionStrings("NorthwindConnectionString").ConnectionString Dim conn As New Data.SqlClient.SqlConnection(strcon) Dim cmdText As String = "UPDATE Orders SET CustomerID = @CustomerID, EmployeeID = @EmployeeID, OrderDate = @OrderDate, RequiredDate = @RequiredDate WHERE OrderID = @OrderID" Dim updateCmd As Data.SqlClient.SqlCommand = New Data.SqlClient.SqlCommand(cmdText, conn) updateCmd.Parameters.Add(New Data.SqlClient.SqlParameter("@OrderID", Data.SqlDbType.Int, 4, "OrderID")) updateCmd.Parameters.Add(New Data.SqlClient.SqlParameter("@CustomerID", Data.SqlDbType.NVarChar, 5, "CustomerID")) updateCmd.Parameters.Add(New Data.SqlClient.SqlParameter("@EmployeeID", Data.SqlDbType.Int, 4, "EmployeeID")) updateCmd.Parameters.Add(New Data.SqlClient.SqlParameter("@OrderDate", Data.SqlDbType.DateTime, 8, "OrderDate")) updateCmd.Parameters.Add(New Data.SqlClient.SqlParameter("@RequiredDate", Data.SqlDbType.DateTime, 8, "RequiredDate")) Dim sv As FarPoint.Web.Spread.SheetView = e.SheetView Dim keyValue As String = sv.GetDataKey(e.CommandArgument) ' 行を検索します。 Dim rowFlag As Boolean = False Dim keyCol As Integer = 0 'OrderID列 Dim r As Integer For r = 0 To sv.RowCount - 1 Dim tmp As String = sv.GetValue(r, keyCol) If (tmp = keyValue) Then rowFlag = True Exit For End If Next If Not rowFlag Then Return End If Dim i As Int32 For i = 0 To sv.ColumnCount - 1 Dim colName As String = sv.GetColumnLabel(0, i) If (Not e.EditValues.Item(i) Is FarPoint.Web.Spread.FpSpread.Unchanged) Then updateCmd.Parameters("@" & colName).Value = e.EditValues.Item(i) ElseIf (updateCmd.Parameters.Contains("@" & colName)) Then updateCmd.Parameters("@" & colName).Value = sv.GetValue(r, i) End If Next Try conn.Open() i = updateCmd.ExecuteNonQuery() Catch ex As Exception ' データベースのアップデートに失敗した場合 Throw ex Finally conn.Close() End Try End Sub
サンプル2
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load 'ページを初期化する ユーザー コードをここに挿入します。 If Not Page.IsPostBack Then With FpSpread1.Pager .Position = FarPoint.Web.Spread.PagerPosition.TopCommandBar .Mode = FarPoint.Web.Spread.PagerMode.Both End With End If '最上行を取得します。 Dim topRow As Integer = FpSpread1.Sheets(0).TopRow 'データを取得します。 SetDataModel(topRow) End Sub Public Sub SetDataModel(ByVal topRow As Integer) 'strcon変数に適切な接続文字列を設定してください。 Dim strcon As String = ConfigurationManager.ConnectionStrings("NorthwindConnectionString").ConnectionString Dim conn As New Data.SqlClient.SqlConnection(strcon) Dim adapt As Data.SqlClient.SqlDataAdapter Dim ps As Integer = FpSpread1.Sheets(0).PageSize Dim rowCount As Integer Dim firstID As Integer conn.Open() '全体の行数を取得 Dim dbCmd As Data.SqlClient.SqlCommand = New Data.SqlClient.SqlCommand("SELECT COUNT(OrderID) from Orders", conn) rowCount = CType(dbCmd.ExecuteScalar(), Integer) 'ID列の最小値を取得 dbCmd = New Data.SqlClient.SqlCommand("SELECT MIN(OrderID) from Orders", conn) firstID = CType(dbCmd.ExecuteScalar(), Integer) dbCmd = New Data.SqlClient.SqlCommand("SELECT Top " & ps & " OrderID, CustomerID, EmployeeID, " & "OrderDate, RequiredDate FROM Orders Where OrderID >=" & (firstID + topRow) & " Order by OrderID") Dim ds As New Data.DataSet FpSpread1.Sheets(0).IsTrackingViewState = False adapt = New Data.SqlClient.SqlDataAdapter(dbCmd.CommandText, conn) adapt.Fill(ds, "Orders") Dim model As MyModel = New MyModel(ds, "Orders") model.TopRow = topRow '全体の行数を設定します。 model.RowCount = rowCount 'データモデルを設定します。 FpSpread1.Sheets(0).DataModel = model conn.Close() End Sub Private Sub FpSpread1_TopRowChanged(ByVal sender As Object, ByVal e As FarPoint.Web.Spread.SpreadCommandEventArgs) Handles FpSpread1.TopRowChanged SetDataModel(e.SheetView.TopRow) End Sub
カスタムデータモデルクラス
※ページに表示する以外のデータにNothingを設定します
Public Class MyModel Inherits FarPoint.Web.Spread.Model.BaseSheetDataModel Private dataset As Data.DataSet = Nothing Private datamember As String = String.Empty Private trow As Integer = 0 Private rCount As Integer = 0 Public Sub New(ByVal ds As Data.DataSet, ByVal dm As String) dataset = ds datamember = dm End Sub Public Overrides Function GetValue(ByVal row As Integer, ByVal col As Integer) As Object Dim dt As Data.DataTable = Me.GetDataTable() If dt Is Nothing Then Return Nothing Else If row < TopRow Or row >= TopRow + dt.Rows.Count Then Return Nothing Else Dim r As Integer = row - TopRow Return dt.Rows(r).Item(col) End If End If End Function Public Overrides Function IsEditable(ByVal row As Integer, ByVal col As Integer) As Boolean Return True End Function Public Function GetDataTable() As Data.DataTable If dataset Is Nothing Then Return Nothing Else If datamember Is Nothing Or datamember = String.Empty Then Return dataset.Tables(0) Else Return dataset.Tables(datamember) End If End If End Function Public Property TopRow() As Integer Get Return trow End Get Set(ByVal Value As Integer) trow = Value End Set End Property Public Overrides Property RowCount() As Integer Get Return rCount End Get Set(ByVal Value As Integer) rCount = Value End Set End Property Public Overrides Property ColumnCount() As Integer Get Dim dt As Data.DataTable = GetDataTable() If (dt Is Nothing) Then Return 0 Else Return dt.Columns.Count End If End Get Set(ByVal Value As Integer) End Set End Property End Class
サンプル3
この例ではより多くのコードが必要になりますが、アプリケーションの効率性はその分高くなります。ユーザーがデータを編集できるようにするには、サンプル1の様にUpdateCommand イベントをアプリケーション側で実装する必要があります。 カスタムデータモデルは、サンプル2のものと同様です。
Private topRow As Int32 'ページ移動直前のTopRowを格納 Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load topRow = FpSpread1.Sheets(0).TopRow SetDataModel(topRow, topRow) End Sub Private Sub FpSpread1_TopRowChanged(ByVal sender As Object, ByVal e As FarPoint.Web.Spread.SpreadCommandEventArgs) Handles FpSpread1.TopRowChanged SetDataModel(topRow, e.SheetView.TopRow) End Sub Public Sub SetDataModel(ByVal oldTopRow As Integer, ByVal newTopRow As Integer) 'strcon変数に適切な接続文字列を設定してください。 Dim strcon As String = ConfigurationManager.ConnectionStrings("NorthwindConnectionString").ConnectionString Dim conn As New Data.SqlClient.SqlConnection(strcon) Dim adapt As Data.SqlClient.SqlDataAdapter Dim dbCmd As New Data.SqlClient.SqlCommand(Nothing, conn) Dim firstOrderID As Integer = -1 Dim lastOrderID As Integer = -1 If Not ViewState("lastOrderID") Is Nothing Then lastOrderID = ViewState("lastOrderID") End If If Not ViewState("firstOrderID") Is Nothing Then firstOrderID = ViewState("firstOrderID") End If Dim ps As Integer = FpSpread1.Sheets(0).PageSize If newTopRow > oldTopRow Then '[次へ] ボタン dbCmd.CommandText = "SELECT Top " & ps & " OrderID, CustomerID, EmployeeID, OrderDate, RequiredDate FROM Orders" & " Where OrderID >" & lastOrderID & " Order by OrderID" ElseIf newTopRow = oldTopRow Then '初回読み込み dbCmd.CommandText = "SELECT Top " & ps & " OrderID, CustomerID, EmployeeID, OrderDate, RequiredDate FROM Orders" & " Where OrderID >=" & firstOrderID & " Order by OrderID" Else '[戻る] ボタン dbCmd.CommandText = "SELECT Top " & ps & " OrderID, CustomerID, EmployeeID, OrderDate, RequiredDate FROM Orders" & " Where OrderID <" & firstOrderID & " Order by OrderID DESC" End If Dim ds As New Data.DataSet() FpSpread1.Sheets(0).IsTrackingViewState = False adapt = New Data.SqlClient.SqlDataAdapter(dbCmd.CommandText, conn) conn.Open() adapt.Fill(ds, "Orders") If newTopRow < oldTopRow Then ' Orderを保存します Dim tmpTable As Data.DataTable = ds.Tables("Orders").Clone() adapt.Fill(tmpTable) ds.Tables("Orders").Clear() Dim dr As Data.DataRow Dim i As Integer For i = 0 To tmpTable.Rows.Count - 1 dr = tmpTable.Rows(tmpTable.Rows.Count - 1 - i) ds.Tables("Orders").ImportRow(dr) Next End If Dim model As MyModel = New MyModel(ds, "Orders") model.TopRow = newTopRow dbCmd = New Data.SqlClient.SqlCommand("select count(*) from orders", conn) model.RowCount = CType(dbCmd.ExecuteScalar(), Integer) conn.Close() FpSpread1.Sheets(0).DataModel = model ViewState("firstOrderID") = ds.Tables("Orders").Rows(0).Item("OrderID") Dim dtcount As Integer = ds.Tables("Orders").Rows.Count ViewState("lastOrderID") = ds.Tables("Orders").Rows(dtcount - 1).Item("OrderID") End Sub