You could do this quite easily with a GridView if you switch on AllowPaging
and set the PageSize
to 50. But it will be horribly inefficient - every time you move to a new page it'll read all 1 000 000 rows, work out which 50 it needs to display, and throw the rest away.
What you want instead is a stored proc in your database that takes the page number that you want to display, works out the set of rows on that page and returns them to the ASP.NET page. If you're using SQL Server 2005/2008 your best bet is to use a Common Table Expression, so your stored proc will look something like this (this is for the Northwind db):
CREATE PROC [dbo].[PagedOrderList]
@PageNumber INTEGER
AS
SET NOCOUNT ON
DECLARE @lowerRecordNumber INTEGER
DECLARE @upperRecordNumber INTEGER
-- Work out the record numbers that bound the page
SET @lowerRecordNumber = ((@pageNumber - 1) * 50) + 1
SET @upperRecordNumber = (@pageNumber * 50);
-- Create a CTE with all the records numbered
WITH OrdersCTE ([RowNumber],[OrderId],[OrderDate],[RequiredDate],[ShippedDate],
[CompanyName],[Value])
AS
(
SELECT
ROW_NUMBER() OVER(ORDER BY o.[OrderId]),
o.OrderID,
o.OrderDate,
o.RequiredDate,
o.ShippedDate,
c.CompanyName,
SUM(od.Quantity * od.UnitPrice) AS [Value]
FROM
Orders o INNER JOIN [Order Details] od ON o.OrderID = od.OrderID
INNER JOIN Customers c ON o.CustomerID = c.CustomerID
GROUP BY o.OrderID, o.OrderDate, o.RequiredDate, o.ShippedDate, c.CompanyName
)
-- Select the rows from the CTE that fall between the bounds we worked out
SELECT *
FROM OrdersCTE
WHERE [RowNumber] BETWEEN @lowerRecordNumber AND @upperRecordNumber
Now, back to your page. You'll need to put in a DataGrid - they have better support for custom paging than anything else - and set AllowCustomPaging
to True. You might find it easier to have one method that calls your stored proc with the page number, then you can add Previous, Next, First, Last, +10, -10 buttons - whatever you want, just work out the page number and pass it to the method.
Private Sub loadData(ByVal pageNumber As Integer)
Dim orderDataTable As DataTable
'This uses the Microsoft Enterprise Library for data access
Dim DAL As Database
Dim cmd As DbCommand
DAL = DatabaseFactory.CreateDatabase("Northwind")
cmd = DAL.GetStoredProcCommand("PagedOrderList")
'Pass the page number to the stored proc
DAL.AddInParameter(cmd, "@pageNumber", DbType.Int32, pageNumber)
'Get a DataTable back with the 50 rows we want
orderDataTable = DAL.ExecuteDataSet(cmd).Tables(0)
'Bind the data to the grid
With OrderDataGrid
.DataSource = orderDataTable
.DataBind()
'Set the page number so we know where we are in the dataset
.CurrentPageIndex = pageNumber
End With
End Sub
Private Sub PreviousButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles PreviousButton.Click
If OrderDataGrid.CurrentPageIndex = 0 Then
'Make sure we don't try to load a negative page number
Else
'Work out the previous page number and load the data for it
Call loadData(OrderDataGrid.CurrentPageIndex - 1)
End If
End Sub
Private Sub NextButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles NextButton.Click
'Work out the nextpage number and load the data for it
Call loadData(OrderDataGrid.CurrentPageIndex + 1)
End Sub