基本上信息显示的地方都离不开分页
刚接触asp.net的时候还没有能力考虑效率的问题,把所有的分页都交给数据控件自己搞定了,用得最多的就是gridview。好处是很方便,还可通过点击表头实现自定义排序,缺点是后台数据流量太大,在数据库数据量比较大的时候速度比较慢,多用户并发的时候更加明显。
随着接触asp.net的时间比较长,慢慢的开始考虑一些效率、优化的内容。为了考虑效率,结合理论和实验分析了一下分页。
实现思想:基本放弃了控件托管,通过手动取回每页数据实现分页。
注意的问题:每次页面的状态模板切换的时候,页面需要重新dataload(下面有这个方法)一次(比如从itemtemplate切换到edittemplate,但是要确保databind事件只执行一次)
1.后台
a)通过存储过程返回每页数据:比较理想的方案是使用cursor访问数据放到表变量里,然后通过表变量一次性返回数据
b)linq(其实底层实现还是双top):query.Skip(currentpage * pagesize).Take(pagesize).ToList()
2.前台
网页代码:
<br />
<asp:Button ID="btnPageFirst" runat="server" Text="首 页" οnclick="btnPageFirst_Click" Enabled="false"/>
<asp:Button ID="btnPagePreview" runat="server" Text="上一页" οnclick="btnPagePreview_Click" Enabled="false"/>
<asp:Button ID="btnPageNext" runat="server" Text="下一页" οnclick="btnPageNext_Click" Enabled="false"/>
<asp:Button ID="btnPageLast" runat="server" Text="末 页" οnclick="btnPageLast_Click" Enabled="false"/><br />
共<asp:Label ID="lblTotalPage" runat="server" Text=""></asp:Label>页<br />
第<asp:Label ID="lblCurrentPage" runat="server" Text=""></asp:Label>页<br />
每页<asp:Label ID="lblPageSize" runat="server" Text=""></asp:Label>条<br />
<br />
codebehind:
//以下为分页控制方法
protected void dataLoad()
{
dao.InfoDao id = new dao.InfoDao();
//currentpage从0开始
switch (hidfViewSwitch.Value)
{
case "L":
//分级浏览
this.reptAllInfo.DataSource = id.getInfoByDirid(
Convert.ToInt32(ViewState["dirid"]),
Convert.ToInt32(ViewState["currentpage"]),
Convert.ToInt32(ViewState["pagesize"]));
this.reptAllInfo.DataBind();
//total实际从1开始
if (null == ViewState["total"])
{
int total = (int)Math.Ceiling((double)
id.getInfoByDirid_count(Convert.ToInt32(ViewState["dirid"]))
/ (double)model.UserConst.uc_page_setting_info_per_page);
ViewState["total"] = total;
}
break;
case "A":
//全部浏览
this.reptAllInfo.DataSource = id.getInfoByLevel1id(
Convert.ToInt32(ViewState["level1id"]),
Convert.ToInt32(ViewState["currentpage"]),
Convert.ToInt32(ViewState["pagesize"]));
this.reptAllInfo.DataBind();
//total实际从1开始
if (null == ViewState["total"])
{
int total = (int)Math.Ceiling((double)
id.getInfoByLevel1id_count(Convert.ToInt32(Convert.ToInt32(ViewState["level1id"])))
/ (double)model.UserConst.uc_page_setting_info_per_page);
ViewState["total"] = total;
}
break;
case "E":
//分级精华浏览
this.reptAllInfo.DataSource = id.getInfoByDiridEliteOnly(
Convert.ToInt32(ViewState["dirid"]),
Convert.ToInt32(ViewState["currentpage"]),
Convert.ToInt32(ViewState["pagesize"]));
this.reptAllInfo.DataBind();
//total实际从1开始
if (null == ViewState["total"])
{
int total = (int)Math.Ceiling((double)
id.getInfoByDiridEliteOnly_count(Convert.ToInt32(ViewState["dirid"]))
/ (double)model.UserConst.uc_page_setting_info_per_page);
ViewState["total"] = total;
}
break;
}
//设置分页按钮
pageButtonSet();
}
protected void resetViewState()
{
ViewState["pagesize"] = model.UserConst.uc_page_setting_info_per_page;
ViewState["currentpage"] = "0";
if (null != ViewState["total"])
ViewState.Remove("total");
}
protected void btnPageFirst_Click(object sender, EventArgs e)
{
//重新计算一下总数
resetViewState();
dataLoad();
}
protected void btnPagePreview_Click(object sender, EventArgs e)
{
int currentpage = Convert.ToInt32(ViewState["currentpage"].ToString());
if (currentpage > 0)
ViewState["currentpage"] = (--currentpage).ToString();
dataLoad();
}
protected void btnPageNext_Click(object sender, EventArgs e)
{
int total = Convert.ToInt32(ViewState["total"].ToString());
int currentpage = Convert.ToInt32(ViewState["currentpage"].ToString());
if (currentpage < (total - 1))
ViewState["currentpage"] = (++currentpage).ToString();
dataLoad();
}
protected void btnPageLast_Click(object sender, EventArgs e)
{
int total = Convert.ToInt32(ViewState["total"].ToString());
ViewState["currentpage"] = --total;
dataLoad();
}
protected void pageButtonSet()
{
int total = Convert.ToInt32(ViewState["total"].ToString());
int currentpage = Convert.ToInt32(ViewState["currentpage"].ToString());
int pagesize = Convert.ToInt32(ViewState["pagesize"].ToString());
//设定页面显示
this.lblCurrentPage.Text = (currentpage + 1).ToString();
this.lblPageSize.Text = pagesize.ToString();
this.lblTotalPage.Text = total.ToString();
//只有一页时,按钮都不可用
if (total == 1 || total == 0)
{
this.btnPageFirst.Enabled = false;
this.btnPageLast.Enabled = false;
this.btnPageNext.Enabled = false;
this.btnPagePreview.Enabled = false;
return;
}
//首页
else if (currentpage == 0)
{
this.btnPageFirst.Enabled = false;
this.btnPageLast.Enabled = true;
this.btnPageNext.Enabled = true;
this.btnPagePreview.Enabled = false;
}
//末页
else if (currentpage == (total - 1))
{
this.btnPageFirst.Enabled = true;
this.btnPageLast.Enabled = false;
this.btnPageNext.Enabled = false;
this.btnPagePreview.Enabled = true;
}
//中间页
else
{
this.btnPageFirst.Enabled = true;
this.btnPageLast.Enabled = true;
this.btnPageNext.Enabled = true;
this.btnPagePreview.Enabled = true;
}
}
总结:
在 !ispostback 的前提下调用
resetViewState();
dataload();
来初始化页面
或者把这些个按钮事件封装在一个ascx里,暂时还没有研究。。。