程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> 分頁那回事?

分頁那回事?

編輯:.NET實例教程

混在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()));
    }
}

我將代碼打包,歡迎下載,給出意見.../Files/izxp/Pager.rar

Copy Right By Robo_zou

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved