今天我们项目遇到个问题,查询数据用的分页控件和分页存储过程,但是查询很慢,数据只有50几万条,我很奇怪。我先用存储过程在数据库里测试,发现存储过程执行起来一点也不慢,就是程序慢,我觉得肯定是程序那里有问题,然后我就调试了一下程序,这不看不知道,一看吓一跳,我勒个去,我们这个分页控件的显示页数的下拉列表会显示所有的页数,数据有50几万条,每页10条,一共5万多页,这个下拉列表竟然一下子添加了50几万个选项,可想而知这压力有多大了,怪不得每次浏览浏览器老是要死掉。我决心要改掉这个问题,一次性加载肯定不行,那我就分多次加载,和分页的原理是一样,首次先显示10个选项,即1-10页,然后给他添加一个下十页选项,当他选择上十页的时候再添加下十页的选项,然后自动跳到下一页选项,再添加个上十页的选项,当他选择上十页这个选项时,才添加上十页的选项,然后自动跳到前面一页,这样就解决了一下子加载那么选项导致浏览器崩溃的问题了,下面来看代码,有不足请大家指出,谢谢了
首先,是前台页面,首页比较简单
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="TestForWithForeach.aspx.cs" Inherits="TestForWithForeach" %>
<!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:TextBox ID="txtNum" runat="server"></asp:TextBox>
<asp:Button ID="btnFor" runat="server" Text="测试" οnclick="btnFor_Click" />
<asp:DropDownList ID="drpPage" runat="server"
onselectedindexchanged="drpPage_SelectedIndexChanged" AutoPostBack="true">
</asp:DropDownList>
</div>
</form>
</body>
</html>
然后是后台代码
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
public partial class TestForWithForeach : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
ViewState["CurrentNum"] = "0";
}
protected void btnFor_Click(object sender, EventArgs e)
{
//每次进去清楚选项
drpPage.Items.Clear();
//获取数量
int pageTotal = 0;
pageTotal = int.Parse(txtNum.Text);
//判断选项是否选择的为第一项
if (ViewState["CurrentNum"] == "0")
{
//判断数量是否大于10,如果大于10就添加下十页这个选项,并循环到10就好了
if (pageTotal / 10 >= 1)
{
for (int j = 0; j < 10; j++)
{
drpPage.Items.Add(new ListItem((j + 1).ToString(), j.ToString()));
}
drpPage.Items.Add(new ListItem("下十页", "next"));
drpPage.SelectedValue = ViewState["CurrentNum"].ToString();
}
else
{
//如果不大于10直接循环到底,不用加下十页
for (int j = 0; j < pageTotal; j++)
{
drpPage.Items.Add(new ListItem((j + 1).ToString(), j.ToString()));
}
drpPage.SelectedValue = ViewState["CurrentNum"].ToString();
}
}
else if (ViewState["CurrentNum"].ToString().Split(',').Length > 1) //判断是否点击下十页,或者上十页,因为下面下拉列表如果点击上十页或者下十页会传字符和选项值,用逗号分开
{
string[] tValues = ViewState["CurrentNum"].ToString().Split(','); //将传过来的值分割获取
int currentNum = int.Parse(tValues[0]); //获取起始选项值
if (tValues[1] == "next") //根据获取的值来判断是点击了上十页还是下十页
{
drpPage.Items.Add(new ListItem("上十页", "previous")); //因为是点击的下十页,所以肯定有上十页,所以直接加上上十页选项
if (currentNum + 10 < pageTotal) //判断选项值加上10是否超过了最大
{
for (int i = currentNum + 1; i <= currentNum + 10; i++)
{
drpPage.Items.Add(new ListItem(i.ToString(), (i - 1).ToString()));
}
drpPage.Items.Add(new ListItem("下十页", "next")); //因为末尾选项值没有超过最大数,所以要加上下十页这个选项
}
else
{
for (int i = currentNum + 1; i <= pageTotal; i++)
{
drpPage.Items.Add(new ListItem(i.ToString(), (i - 1).ToString()));
}
}
drpPage.SelectedIndex = 1;
}
else if (tValues[1] == "previous") //选择了上十页
{
if (currentNum - 10 != 1) //判断是否在第一个十页选项,即1-10这个段
{
drpPage.Items.Add(new ListItem("上十页", "previous")); //因为不是第一个十页选项所以加上上十页选项
}
if (currentNum - 10 >= 1) //如果选项起点值在第一个或者不是第一个添加选项,因为有上十页所以肯定有下下十页
{
for (int i = currentNum - 10; i <= currentNum - 1; i++)
{
drpPage.Items.Add(new ListItem(i.ToString(), (i - 1).ToString()));
}
drpPage.Items.Add(new ListItem("下十页", "next"));
}
drpPage.SelectedValue = (currentNum - 2).ToString();
}
}
else
{
//通过模10和除10来确定有多少个10页段
int currentNum = int.Parse(ViewState["CurrentNum"].ToString());
int a = currentNum / 10; //获取相除结果
int b = currentNum % 10; //获取模后的余数
int begin = 0;
int end = 0;
if (b == 0)
{
if (a > 1) //判读是否大于10页
{
drpPage.Items.Add(new ListItem("上十页", "previous"));
}
begin = a * 10 - 9;
end = a * 10;
for (int i = begin; i <= end; i++)
{
drpPage.Items.Add(new ListItem(i.ToString(), (i - 1).ToString()));
}
if (pageTotal > end)
{
drpPage.Items.Add(new ListItem("下十页", "next"));
}
}
else
{
if (a >= 1) //判读是否大于10页
{
drpPage.Items.Add(new ListItem("上十页", "previous"));
}
begin = (a + 1) * 10 - 9;
end = (a + 1) * 10;
if (end > pageTotal)
{
end = pageTotal;
}
for (int i = begin; i <= end; i++)
{
drpPage.Items.Add(new ListItem(i.ToString(), (i - 1).ToString()));
}
if (pageTotal > end)
{
drpPage.Items.Add(new ListItem("下十页", "next"));
}
}
drpPage.SelectedValue = (currentNum-1).ToString();
}
}
protected void drpPage_SelectedIndexChanged(object sender, EventArgs e)
{
if (drpPage.SelectedValue == "next")
{
ViewState["CurrentNum"] = drpPage.Items[drpPage.SelectedIndex - 1].Text+","+"next";
btnFor_Click(null, null);
}
else if (drpPage.SelectedValue == "previous")
{
ViewState["CurrentNum"] = drpPage.Items[drpPage.SelectedIndex + 1].Text + "," + "previous";
btnFor_Click(null, null);
}
else
{
ViewState["CurrentNum"] = drpPage.SelectedItem.Text;
btnFor_Click(null, null);
}
}
}