浅谈分页那回事_.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的引用(直接引入和间接引入)
- 三层+存储过程实现分页示例代码