淺談分頁那回事_.Net教程
推薦:解析ASP.NET WebForm頁面內容輸出方式這次我們談的話題是Web Form頁面上輸出內容的方式。這其實是一個非常舊的話題了,因為本文的內容甚至可以運用于ASP.NET 1.1之上。不過這個話題的適用范圍很廣,因為即使是目前最新的ASP.NET MVC框架,它的默認視圖引擎依舊是基于ASP.NET WebForm的(如Page,
混在web上,那有不同分頁打交道的,分頁偏偏又是一個硬傷,總是不能找到一個通用的解決方法,即使用上分頁自定義/用戶控件感覺還是少了點什么,性能。web頁面一次一般顯示10行數據為好,但往往很多時候我們從數據庫中查出來上萬條數據,這個時候我們要在上萬條數據中顯示10條,那就必須分頁。分頁的第一問題就是分頁數據。
1.分頁數據:分頁的數據分為兩種,一種是在數據庫中只取需要的10條數據,這也是性能提升的標致,一種是全盤拖出,放到程序緩存中再用程序來分頁。
1.1 第一種取數據方式有select top [PageSize] * from [Table] where id not in(select top [CurrentPage-1] [PageSize] id from [Table] ----用于access,mssql當中
另一種是存儲過程,這也是最快的取數據方式
ALTER PROCEDURE GetAuthors @PageIndex int, @PageSize int AS BEGIN -- Set the page bounds DECLARE @PageLowerBound int DECLARE @PageUpperBound int DECLARE @TotalRecords int SET @PageLowerBound = @PageSize * (@PageIndex-1) SET @PageUpperBound = @PageSize*@PageIndex-1 -- Create a temp table TO store the select results CREATE TABLE #PageIndexForAuthors ( IndexId int IDENTITY (0, 1) NOT NULL, au_id varchar(11), au_lname varchar(40), au_fname varchar(20), phone char(12), address varchar(40), city varchar(20), state char(2), zip char(5), contract bit ) -- Insert into our temp table INSERT INTO #PageIndexForAuthors (au_id ,au_lname,au_fname,phone,address,city,state,zip,contract) SELECT * FROM authors ORDER BY au_id SELECT @TotalRecords = @@ROWCOUNT SELECT * FROM #PageIndexForAuthors WHERE IndexId between @PageLowerBound AND @PageUpperBound ORDER BY au_id RETURN @TotalRecords END GO |
上面這段存儲過程是仿微軟的寫法,微軟在Membership里面采用也是這存儲過程分頁。
其他數據庫取數據也有不同,sql2005有行號函數,oracle也有,mysql就更好取了limit 10,20
1.2第二種就是全部數據取出來再做緩存,數據用程序處理,.ado/jdbc有定位法,Adapter.Fill()用這個填充需要的數據,GridView自定義分頁事件就是使用這個,看到很多自定義控件也使用這種方式。
2.分頁采取何種方式了,現在網頁都講究Seo,所以在前臺分頁的時候我摒棄PostBack方式,而采用URL方式.不采PostBack也就不需要用到ViewState[“PageNo”]存取數據,每次分頁的時候都重新加載,所以視圖狀態就沒撒用.
好了,現在很清楚,為了效率,為了SEO,混口飯吃真不容易,數據采用存儲過程從數據庫中取所需的數據,并返回總共條數.分頁采用URL方式,一是為了urlRewrite和seo,至于postback提倡在后臺分頁,畢竟方便。
那現在就到了實現階段,數據顯示控件肯定是Repeater/DataList/GridView統殺.剛開始我是想把分頁控件和數據顯示在一起,但是若使用存儲過程傳遞參數比較麻煩,不使的存儲過程參數個數是不一樣的,所以決定采用數據顯示和分頁控件分離的方法,分頁控件只傳遞總記錄數就可以了.
所以即想當爹又當媽,那是很累的,現在主要使用存儲過程從數據庫取出所需的數據,分頁控件又采用URL,到止分頁效率高了,SEO也實現了,但是三層架構中不好使,三層架構中要傳參中加頁碼也可以使,代碼如下
這是頁面代碼:
public partial class PagerDemo : System.Web.UI.Page { private int TotalRecords; protected void Page_Load(object sender, EventArgs e) { Repeater1.DataSource = GetTable(); Repeater1.DataBind(); Pager1.TotalRecords = TotalRecords ; } private DataTable GetTable() { string connStr = ConfigurationManager.ConnectionStrings["pubsConnectionString"].ConnectionString; DataTable dt = new DataTable(); using (SqlConnection conn = new SqlConnection(connStr)) { SqlParameter[] prms = new SqlParameter[3]; prms[0] = new SqlParameter("@PageIndex", SqlDbType.Int); prms[0].Value = Pager1.PageIndex; prms[1] = new SqlParameter("@PageSize", SqlDbType.Int); prms[1].Value = Pager1.PageSize; prms[2] = new SqlParameter("@TotalRecords", SqlDbType.Int); prms[2].Direction = ParameterDirection.ReturnValue; SqlCommand cmd = conn.CreateCommand(); cmd.Parameters.AddRange(prms); cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = "GetAuthors"; SqlDataAdapter Adapter = new SqlDataAdapter(); Adapter.SelectCommand = cmd; try { conn.Open(); Adapter.Fill(dt); TotalRecords = int.Parse(cmd.Parameters["@TotalRecords"].Value.ToString()); return dt; } catch (Exception ex) { throw ex; } } } } |
這是用戶控件代碼:
Code
public partial class Pager : System.Web.UI.UserControl
{
private int _totalRecords;
private int _pageSize = 10;
private int _maxPagesShown = 10;
private System.Collections.Generic.List<string> queryString;
protected void Page_Load(object sender, EventArgs e)
{
SetPages();
}
public int TotalRecords
{
get { return _totalRecords; }
set { _totalRecords = value; }
}
public int PageIndex
{
get
{
return Request.QueryString["PageNo"] == null ? 1 : int.Parse(Request.QueryString["PageNo"]);
}
}
public int PageSize
{
get { return _pageSize; }
set { _pageSize = value; }
}
public int MaxPagesShown
{
set { _maxPagesShown = value; }
}
public int PageCount
{
get { return TotalRecords / PageSize + 1; }
}
private void SetPages()
{
Panel1.Controls.Clear();
HyperLink link;
if (PageIndex - _maxPagesShown > 1)
{
link = new HyperLink(); link.Text = "<<"; link.NavigateUrl = MakeLink("1"); Panel1.Controls.Add(link);
}
if (PageIndex > 1)
{
link = new HyperLink(); link.Text = "<"; link.NavigateUrl = MakeLink(PageIndex - 1); Panel1.Controls.Add(link);
}
for (int i = PageIndex - _maxPagesShown; i <= PageIndex + _maxPagesShown; i++)
{
if (i > 0 && i <= PageCount)
{
if (PageIndex == i)
{
link = new HyperLink(); link.Text = "Page " + i.ToString(); link.CssClass = "selected"; Panel1.Controls.Add(link);
}
else
{
link = new HyperLink(); link.Text = i.ToString(); link.NavigateUrl = MakeLink(i); Panel1.Controls.Add(link);
}
}
}
if (PageIndex < PageCount)
{
link = new HyperLink(); link.Text = ">"; link.NavigateUrl = MakeLink(PageIndex + 1); Panel1.Controls.Add(link);
}
if (PageIndex + _maxPagesShown < PageCount)
{
link = new HyperLink(); link.Text = ">>"; link.NavigateUrl = MakeLink(PageCount); Panel1.Controls.Add(link);
}
}
private string MakeLink(Object pageID)
{
string currentPageID = pageID.ToString();
queryString = new System.Collections.Generic.List<string>();
foreach (string key in Request.QueryString.Keys)
{
if (key != "PageNo")
{
queryString.Add(key + "=" + Request.QueryString[key]);
}
}
queryString.Add("PageNo=" + pageID.ToString());
string filePath = Request.CurrentExecutionFilePath;
return String.Format(filePath + "?{0}", String.Join("&", queryString.ToArray()));
}
}
分享:揭秘.Net開發人員必知的八個網站當前全球有數百萬的開發人員在使用微軟的.NET技術。如果你是其中之一,或者想要成為其中之一的話,我下面將要列出的每一個站點都應該是你的最愛,都應該收藏到書簽中去。 對于不熟悉.NET技術的朋友,需要說明一下,.NET提供了一個平臺和一些相應的工具,編程
- asp.net如何得到GRIDVIEW中某行某列值的方法
- .net SMTP發送Email實例(可帶附件)
- js實現廣告漂浮效果的小例子
- asp.net Repeater 數據綁定的具體實現
- Asp.Net 無刷新文件上傳并顯示進度條的實現方法及思路
- Asp.net獲取客戶端IP常見代碼存在的偽造IP問題探討
- VS2010 水晶報表的使用方法
- ASP.NET中操作SQL數據庫(連接字符串的配置及獲取)
- asp.net頁面傳值測試實例代碼
- DataGridView - DataGridViewCheckBoxCell的使用介紹
- asp.net中javascript的引用(直接引入和間接引入)
- 三層+存儲過程實現分頁示例代碼