網站分頁功能的實現(Entity Framework和ADO.NET兩種綜述)
專案中用到了分頁,上次是用的是Entity Framework,這次用ADO.NET,都是老師講的,有必要總結一下,加深下記憶。
一、Entity Framework中完成分頁
老師就講了一種,在從資料庫倒序查詢到想要的list後,在對應的使用者控制元件的.cs檔案中用了兩個方法。程式碼如下:
listnew= list.Skip( pagesize*(pagenow-1)).Take(pagesize).ToList();
其中pagesize代表一個頁面要顯示的個數,pagenow代表當前頁面。
Skip()代表跳過序列中指定量的元素,返回剩餘的元素。
Take()代表從序列的開頭返回指定數量的連續元素。
假如一頁顯示3條內容,現在要顯示第5頁的內容,就先擷取前四頁的內容後,取下面緊接著的3條。
注意,要使用SKip()和Take()必須引用名稱空間using system.Linq;而這個名稱空間必須在.NET Framework3.5版本以上才具有。
二、ADO.NET實現分頁
這個是今天我總結的重點。老師說實現它的SQL語句有三種,講了兩種,還有一種利用 ROW_NUMBER(),不過沒講,於是在網上搜了一下,三種方法如下:
資料庫中表為Users,欄位有id,name,pwd,和上面一樣,每頁顯示3條資料,要求顯示第5頁的內容
1、
Sselect top 3 * from users
where id not in
(select top(3*4) id from users order by id desc )
order by id desc
這種方法跟上面Entity Framework中的方法一樣,都是先跳過一些資料,然後取得所需資料。
不建議使用此方法,因為not in,如果資料多的話,效率會低很多,推薦下面兩種方法。
2、
當要顯示頁為1時
select top 3 * from users order by id desc
當要顯示的頁大於1時(比方說還是上面的求第五頁)
select top 3 * from users where id <
(select top 1 id from
(select top(3*4) * from users order by id desc) as tab
order by id) order by id desc
分析一下此SQL語句,先看select top(3*4) * from users order by id desc,是把前四頁的內容按倒序找出來,
select top 1 id from (select top(3*4) * from users order by id desc) as tab order by id 是把剛才倒序找出來的內容當做表,然後把它按照id的升序進行排列,找到第一個也就是最小的那個id.
然後就是整句合起來看,取得倒序排列後前三個比剛才得到的那個id小的資料。
說的有點繞,其實也很簡單,跟第一種方法比,都是把前四頁的資料先找出來,而第一種方法是接著找前三個不屬於前四頁資料的內容(當然是倒序後),第二種方法是找出來後,再找那個最小的id,然後取前三個比這個id小的內容(當然也是倒序後)。
不懂的話,可以自己建張表,然後分我這三步看一下結果就知道了。
3、
select * from( select row_number() over(order by id desc)as rownum,* from users) as newtable where rownum between 13 and 15
此方法用到 row_number() over()函式,資料庫在SQL2005版本以上才能使用
推薦使用此方法,因為簡單嘛。
三、asp.net 實現分頁的具體步驟
上面說的只是如何把想要的資料顯示出來,如果是entity framework ,查出來全部使用者list後,在.aspx.cs檔案中直接用skip()和take()方法就可以了。如果是ado.net,必須把全部使用者list1和當前頁面要顯示的list2都取出來,取全部使用者list1的目的是為了得到它的count屬性,因為在下面做分頁的第一步中,需要用到總量count。當然,不必每次都去取,可以取出來以後放到快取裡,這個是題外話了。下面說一下就具體怎麼實現:
1、先建立一個使用者控制元件PageControl,在他的cs檔案程式碼如下
public partial class Admin_PageControl : System.Web.UI.UserControl
{
protected string str;
private int pagesize;
public int Pagesize
{
get { return pagesize; }
set { pagesize = value; }
}
private int pagenow;
public int Pagenow
{
get { return pagenow; }
set { pagenow = value; }
}
private int count;//總共的資料條數
public int Count
{
get { return count; }
set { count = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
NewPage();
}
private void NewPage()
{
StringBuilder sb = new StringBuilder();// 話說劍哥(我們老師)不讓定義成sb來著。。
int pagecount = count % pagesize == 0 ? count / pagesize : count / pagesize + 1;
int uppage = pagenow == 1 ? 1 : pagenow - 1;//上一頁
int downpage = pagenow == pagecount ? pagecount : pagenow + 1;//下一頁
sb.AppendFormat("<a href='?page={0}' >首頁</a> ", 1);
sb.AppendFormat("<a href='?page={0}' >上一頁</a> ", uppage);
sb.AppendFormat("<a href='?page={0}' >下一頁</a> ", downpage);
sb.AppendFormat("<a href='?page={0}' >尾頁</a> ", pagecount);
str = sb.ToString();
}
}
至於它的ascx,直接輸出<%=str%>就行了,樣式表自己設定。
2、在DAL層中把資料查出來,看你用哪種了,如果entity framework,只查出來總共的list就行了,如果是dao.net,還得查當前要顯示的list,而且SQL語句很長,三種SQL語句挑一種,最好用儲存過程,這樣效能會好些。關於儲存過程,以後會再寫篇文章專門總結一下,總覺得自己掌握的不太好。
3、在某個頁面中使用上面做好的使用者控制元件PageControl。舉個例子,假設是MemberPage.aspx這個頁面要用到吧,在頁面中把控制元件加上後,接著在它的.cs頁面中進行操作,
操作包括從資料庫總取資料和對使用者控制元件定義好的屬性進行賦值。具體程式碼如下:
protected List<Member> Memberlist;
protected List<Member> AllMemberlist;
protected void Page_Load(object sender, EventArgs e)
{
NewPage();
}
private void NewPage()
{
int pagesize = 3;//假設每頁顯示三條資料
int pagenow = 1;//當前為第一頁
if (Request.QueryString["page"] != null)
{
pagenow =int.Parse( Request.QueryString["page"]);
}
AdminManager.BLL.UserRolesManageBLL urmb = new AdminManager.BLL.UserRolesManageBLL(); //底層是抽象工廠做的,沒引用名稱空間,這樣路徑清晰點。。
AllMemberlist = urmb.GetAllMember(); //所有使用者資料,在DAL層把它查出來後順便加到快取中,或者從快取中去取出來
Memberlist = urmb.GetMemberList(pagesize,pagenow); //這個是當前頁面要顯示的資料
int count = AllMemberlist.Count;
PageControl1.Pagenow = pagenow; //一下這三個都是對使用者控制元件PageControl的屬性進行賦值
PageControl1.Pagesize = pagesize;
PageControl1.Count = count;
}
注意了,上面的程式碼是針對ado.net的,如果用的是entity framework,那太簡單了,直接把AllMemberlist 取出來後,用Skip()和Take()方法就可以了。
文章剛開始的時候說過了,不再複述。
基本就這些了,看著有些亂,本人菜鳥一枚,上面的程式碼也是自己的練習,如果前面有不對或者不恰當的地方,還請大俠們指正,謝謝。