分頁是 Web 應用程式的核心功能。本文系統整理三種主流分頁策略:
SELECT * FROM News
ORDER BY CreateDate DESC
OFFSET @PageSize * (@PageIndex - 1) ROWS
FETCH NEXT @PageSize ROWS ONLY;
WITH CTE AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY CreateDate DESC) AS RowNum
FROM News
)
SELECT * FROM CTE
WHERE RowNum BETWEEN @StartRow AND @EndRow;
SELECT * FROM News
ORDER BY CreateDate DESC
LIMIT @PageSize OFFSET @Offset;
| 優點 | 缺點 |
|---|---|
| 網路傳輸最少、資料庫壓力最小、支援超大資料量 | 需撰寫動態 SQL、維護複雜、總筆數需額外查詢 |
var pds = new PagedDataSource
{
DataSource = GetAllNews(), // 取回「所有」資料
AllowPaging = true,
PageSize = 16,
CurrentPageIndex = CurrentPage - 1 // 0-based
};
rptNews.DataSource = pds;
rptNews.DataBind();
// 總頁數、總筆數
lblTotalPages.Text = pds.PageCount.ToString();
lblTotalRecords.Text = pds.DataSourceCount.ToString();
Install-Package AspNetPager<%@ Register Assembly="Wuqi.Webdiyer" Namespace="Wuqi.Webdiyer" TagPrefix="webdiyer" %><webdiyer:AspNetPager ID="anpNews" runat="server"
PageSize="16"
RecordCount="0"
NumericButtonCount="10"
AlwaysShow="false"
FirstPageText="首頁"
PrevPageText="上一頁"
NextPageText="下一頁"
LastPageText="尾頁"
CssClass="pagination"
CurrentPageButtonClass="active"
OnPageChanging="anpNews_PageChanging" />
private int _pageIndex = 1;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
_pageIndex = 1;
BindData();
}
}
protected void anpNews_PageChanging(object src, Wuqi.Webdiyer.PageChangingEventArgs e)
{
_pageIndex = e.NewPageIndex;
BindData();
}
private void BindData()
{
// 1. 只取當頁資料 (SQL 分頁)
var list = NewsRepository.GetPage(_pageIndex, anpNews.PageSize);
// 2. 設定總筆數給 AspNetPager
anpNews.RecordCount = NewsRepository.GetTotalCount();
// 3. 繫結 Repeater
rptNews.DataSource = list;
rptNews.DataBind();
}
anpNews.EnableUrlRewriting = true;
anpNews.UrlRewritePattern = "NewsList_{0}.aspx"; // 產生 NewsList_1.aspx, NewsList_2.aspx...
.pagination { display: flex; gap: 4px; justify-content: center; margin: 20px 0; }
.pagination a, .pagination span {
padding: 6px 12px; border: 1px solid #075198; color: #000; text-decoration: none;
}
.pagination a:hover { background: #075198; color: #fff; }
.pagination .active { background: #075198; color: #fff; font-weight: bold; border-color: #075198; }
GridView 內建分頁 (AllowPaging="true") 同屬記憶體內分頁,資料量大時效能不佳。建議搭配 AspNetPager + PagedDataSource 或 SQL 分頁,將 GridView 當純顯示控制項:
protected void gvNews_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
gvNews.PageIndex = e.NewPageIndex;
BindGridView(); // 重新繫結
}
| 場景 | 建議方案 |
|---|---|
| 資料量 > 10 萬筆、高併發 | SQL 分頁 + AspNetPager (UrlRewrite) |
| 資料量 1 萬~10 萬、後台管理 | PagedDataSource + AspNetPager (快取 DataSource) |
| 資料量 < 1 萬、快速開發 | PagedDataSource + GridView 內建分頁 |
| 需 SEO 友善網址 | AspNetPager EnableUrlRewriting + URL Rewrite Module |