淺談分頁那回事_.Net教程

      編輯Tag賺U幣
      教程Tag:暫無Tag,歡迎添加,賺取U幣!

      推薦:解析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 (01NOT 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提供了一個平臺和一些相應的工具,編程

      來源:模板無憂//所屬分類:.Net教程/更新時間:2009-10-30
      相關.Net教程