星期二, 8月 07, 2012

分頁

最近看到專案,裡面的分頁都是用內建的方法來做分頁(資料都塞到 viewstate),每個 grid 抓出來的資料都是上百筆甚至還有上千筆的,效能都是干我屁事,完全沒有考慮品質的問題,把責任都丟給了區網,還有那傳來傳去累到死 browser 跟 iis,如果在資料少的情況下,這樣寫還可以說得過去,如果資料很多那就是管他媽媽嫁給誰的您老師咖好的寫法..

不過換個想法,在 asp.net 裡面,不把資料塞在 viewstate,要多少資料拿多少資料的分頁寫法,很困難嗎?不然大家怎麼會用這個"內建"的寫法,去處理大量資料的問題,所以當然要股溝谷歌大神 survey 一下,看看 asp.net 有啥好的解決方案

[C#] 使用 ObjectDataSource 實作資料來源分頁
[SubText心得]ASP.NET TSQL 效能較佳分頁方法及友善 SEO 的分頁

上面是網路找到的效率好的分頁處理方式,可以參考一下,不過好像不是這麼簡單,在印象中應該不會這麼困難,所以 Bibby 我就自己做做看,看到底分頁可不可以簡單寫!

第一步,懶惰是程式人的進步動力,知道站在巨人的肩膀上,才會飛的高飛的遠(懶就懶都是多說低),所以就去找了一個 thrid party 的分頁元件,可以用 nuget 來下載

AspNetPager paging control
http://en.webdiyer.com/AspNetPager

clip_image001

第二步,把元件加入 Toolbox Panel

clip_image002

clip_image003

clip_image004

clip_image005

clip_image006

第三步,直接 coding 啦,這裡我是用 northwind.mdb 和 entityframework 來做範例

.aspx(把控制項拉到頁面上)

<%@ Page Language="C#" AutoEventWireup="true" 
CodeBehind="Pager.aspx.cs" Inherits="WebApplication1.Pager" %>


<%@ Register Assembly="AspNetPager" Namespace="Wuqi.Webdiyer" TagPrefix="webdiyer" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <asp:GridView ID="GridView1" runat="server">
    </asp:GridView>
    <webdiyer:AspNetPager ID="AspNetPager1" runat="server">
    </webdiyer:AspNetPager>
    </div>
    </form>
   
</body>
</html>


.cs

    public partial class Pager : System.Web.UI.Page
    {
        private int PageSize { get { return 8; } }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            AspNetPager1.PageChanged += new EventHandler(AspNetPager1_PageChanged);
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
                InitForm();
        }

        void AspNetPager1_PageChanged(object sender, EventArgs e)
        {
            var pager = sender as AspNetPager;
            BindData(pager.CurrentPageIndex);
        }

        private void InitForm()
        {
            BindData(1);
        }

        private void BindData(int currentIndex)
        {
            //GridView
            GridView1.DataSource = GetGridViewData(currentIndex);
            GridView1.DataBind();

            //Pager
            AspNetPager1.RecordCount = GetAllData().Count();
            AspNetPager1.CurrentPageIndex = currentIndex;
            AspNetPager1.PageSize = PageSize;
        }

        private List<Products> GetGridViewData(int currentIndex)
        {
            int cIndex = currentIndex - 1;
            return GetAllData().OrderBy(a => a.ProductID)
                             .Skip(cIndex * PageSize)
                             .Take(PageSize).ToList();
        }

        private IQueryable<Products> GetAllData()
        {
            NorthwindEntities db = new NorthwindEntities();
            return db.Products;
        }
    }


畫面

clip_image007

這是到這邊,很初步的寫完了,其實 code 並沒有很多,這寫法的優點是,把分頁跟 grid 處理分開了,也沒有牽扯到 store procedure,所以哪一天你覺得 gridview 不好用,想換成 listview 或是 datalist 就直接換掉,沒有啥需要好考慮的,如果想要用 ado.net 來做到相同的效果,應該也不會有太大的問題,只是換換 method 而已,所以..該會的還是要會,品質該顧的還是要顧,出來混的總有一天要還的!!

PS:這 AspNetPager paging control 的控制項有一堆可以調的東西,可以調的很漂亮,範例醜醜的大家忍耐一下

參考:
http://en.webdiyer.com/AspNetPager
http://en.webdiyer.com/AspNetPagerDemo/

沒有留言: