当前位置: 移动技术网 > IT编程>开发语言>.net > GridView高效分页和搜索功能的实现代码

GridView高效分页和搜索功能的实现代码

2017年12月12日  | 移动技术网IT编程  | 我要评论
前言:         公司项目开发,上周的任务是做基础数据的管理。在sharepoint2010里

前言:

        公司项目开发,上周的任务是做基础数据的管理。在sharepoint2010里边内嵌asp.net的aspx页,遇到了各种各样奇葩的问题,因为之前对sharepoint只是有一些了解,但是没有设计到具体的编程工作,这一次算是初次接触吧。其中有一部分基础数据数据量很大,大致有十多万,因为是对基础数据的维护,所以还需要对数据进行列表展示,增删改查什么的,大家都知道asp.net里边的gridview有自带的分页,但是,那个分页对于少量的数据还好,对于这种数十万的数据量而言,这种分页方式简直就是灾难。网上关于gridview高效分页的东西有很多,找了一个自己改了改。用着效果还不错,和大家分享一下。

        这是分页的效果图

 下边就讲一下具体的实现,首先声明,这个东西是不是我原创的,只是在此基础上进行了修饰和完善。希望能给各位有所启发。

          一、前台布局

复制代码 代码如下:

  <div>
    <div id="main">
    <div id="search">
       <table>
<tr>
<td>
    <asp:label id="lb" runat="server" text="姓名"></asp:label></td>
<td>
    <asp:textbox id="searchname" runat="server"></asp:textbox>
</td>
<td>
    <asp:button id="btnsearch" runat="server" text="查询" onclick="pagerbtncommand_onclick" commandname="search" />
</td>
<td>
    <asp:button id="btnreset" runat="server" text="重置" onclick="btnreset_click" />
</td>
</tr>
</table>
    </div>
    <div id="gridview">
     <asp:gridview id="usergridview" runat="server"  autogeneratecolumns="false">
        <columns>
        <asp:templatefield headertext="用户名">
        <itemtemplate>
            <asp:label id="username" runat="server" text='<%#eval("username") %>'></asp:label>
        </itemtemplate>
        </asp:templatefield>
        <asp:templatefield headertext="单位名称">
        <itemtemplate>
            <asp:label id="displayname" runat="server" text='<%#eval("displayname") %>'></asp:label>
        </itemtemplate>
        </asp:templatefield>
        <asp:templatefield headertext="组织编码">
        <itemtemplate>
            <asp:label id="orgcode" runat="server" text='<%#eval("orgcode") %>'></asp:label>
        </itemtemplate>
        </asp:templatefield>
        <asp:templatefield headertext="组织名称">
        <itemtemplate>
            <asp:label id="orgname" runat="server" text='<%#eval("orgname") %>'></asp:label>
        </itemtemplate>
        </asp:templatefield>
        </columns>
        </asp:gridview>
    </div>
    <div id="page">
    <table>
     <tr>
     <td>
      <asp:label id="lbcurrentpage1" runat="server" text="当前页:"></asp:label>
    <asp:label id="lbcurrentpage" runat="server" text=""></asp:label>
    <asp:label id="lbfenge" runat="server" text="/"></asp:label>
    <asp:label id="lbpagecount" runat="server" text=""></asp:label>
    </td>
     <td>
     <asp:label id="recordscount" runat="server" text="总条数:"></asp:label>
      <asp:label id="lbrecordcount" runat="server" text=""></asp:label>
    </td>
    <td>
<asp:button id="fistpage" runat="server" commandname="" text="首页" onclick="pagerbtncommand_onclick" />
<asp:button id="prevpage" runat="server" commandname="prev" text="上一页"
        onclick="pagerbtncommand_onclick" />
<asp:button id="nextpage" runat="server" commandname="next" text="下一页" onclick="pagerbtncommand_onclick" />
<asp:button id="lastpage" runat="server" commandname="last" text="尾页"
       key="last" onclick="pagerbtncommand_onclick" />
</td>
    <td>
    <asp:label id="lbjumppage" runat="server" text="跳转到第"></asp:label>
    <asp:textbox id="gotopage" runat="server" width="25px"></asp:textbox>
    <asp:label id="lbye" runat="server" text="页"></asp:label>
      <asp:button id="jump" runat="server" text="跳转" commandname="jump" onclick="pagerbtncommand_onclick" />
    </td>
</tr>
</table>
    </div>
    </div>
    </div>

布局的效果如下:

二、后台的代码实现

     我会一点一点向大家讲解清楚,这个分页的原理

     members:这里主要定义几个全局的变量,主要用来记录信息的数量、页的数量和当前页

复制代码 代码如下:

#region members
        const int pagesize = 10;//每页显示信息数量
        int pagescount, recordscount;//记录总页数和信息总条数
        int currentpage, pages, jumppage;//当前页,信息总页数(用来控制按钮失效),跳转页码
        const string count_sql = "select count(*)  from p_user";
        #endregion

methods:  

1、getrecordscount:该方法主要用来获取当前信息的总数,有一个sqlsearch参数,默认的为default,即初始化页面时,查询所有信息的总条数,当用户输入要搜索的用户名进行检索时,获取符合用户检索条件的信息的总条数

复制代码 代码如下:

/// <summary>
       /// 获取信息总数
       /// </summary>
       /// <param name="sqlsearch"></param>
       /// <returns></returns>
       public static int getrecordscount(string sqlrecordscount)
       {
           string sqlquery;
           if (sqlrecordscount == "default")
           {
               sqlquery = count_sql;
           }
           else
           {
               sqlquery = sqlrecordscount;
           }
           int recordcount = 0;
           sqlcommand cmd = new sqlcommand(sqlquery, conn());
           recordcount = convert.toint32(cmd.executescalar());
           cmd.connection.close();
           return recordcount;
       }

2、overpage:该方法主要用来计算剩余页,当前设置的为每页显示10条数据,如何符合条件的数据有11条,则要显示2页

复制代码 代码如下:

/// <summary>
       /// 计算余页
       /// </summary>
       /// <returns></returns>
       public int overpage()
       {
           int pages = 0;
           if (recordscount % pagesize != 0)
               pages = 1;
           else
               pages = 0;
           return pages;
       }

3、modpage:该方法也是用计算余页,主要用来防止sql执行溢出

复制代码 代码如下:

/// <summary>
       /// 计算余页,防止sql语句执行时溢出查询范围
       /// </summary>
       /// <returns></returns>
       public int modpage()
       {
           int pages = 0;
           if (recordscount % pagesize == 0 && recordscount != 0)
               pages = 1;
           else
               pages = 0;
           return pages;
       }

4、conn:该方法用来创建数据连接对象,在使用的时候只需改成自己的数据库名即可 

复制代码 代码如下:

/// <summary>
        /// 数据连接对象
        /// </summary>
        /// <returns></returns>
        public static sqlconnection conn()
        {
            sqlconnection conn = new sqlconnection("data source=.;initial catalog=db_gsl_zcw;integrated security=true");
            conn.open();
            return conn;
        }

5、gridviewdatabind:该方法主要用来数据绑定,如果传入的参数为default则,默认的绑定所有的数据,否则,则绑定过滤过的数据

复制代码 代码如下:

/// <summary>
        /// gridview数据绑定,根据传入参数的不同,进行不同方式的查询,
        /// </summary>
        /// <param name="sqlsearch"></param>
        private void gridviewdatabind(string sqlsearch)
        {
            currentpage = (int)viewstate["pageindex"];
            //从viewstate中读取页码值保存到currentpage变量中进行按钮失效运算
            pages = (int)viewstate["pagescount"];
            //从viewstate中读取总页参数进行按钮失效运算
            //判断四个按钮(首页、上一页、下一页、尾页)状态
            if (currentpage + 1 > 1)//当前页是否为首页
            {
                fistpage.enabled = true;
                prevpage.enabled = true;
            }
            else
            {
                fistpage.enabled = false;
                prevpage.enabled = false;
            }
            if (currentpage == pages)//当前页是否为尾页
            {
                nextpage.enabled = false;
                lastpage.enabled = false;
            }
            else
            {
                nextpage.enabled = true;
                lastpage.enabled = true;
            }
            dataset ds = new dataset();
            string sqlresult;
            //根据传入参数sqlsearch进行判断,如果为default则为默认的分页查询,否则为添加了过滤条件的分页查询
            if (sqlsearch == "default")
            {
                sqlresult = "select top " + pagesize + "user_serialid,username,displayname,orgcode,orgname from p_user where user_serialid not in(select top " + pagesize * currentpage + " user_serialid from p_user order by user_serialid asc) order by user_serialid asc";
            }
            else
            {
                sqlresult = sqlsearch;
            }
            sqldataadapter sqladapter = new sqldataadapter(sqlresult, conn());
            sqladapter.fill(ds, "result");
            usergridview.datasource = ds.tables["result"].defaultview;
            usergridview.databind();
            //显示label控件lbcurrentpaget和文本框控件gotopage状态
            lbcurrentpage.text = (currentpage + 1).tostring();
            gotopage.text = (currentpage + 1).tostring();
            sqladapter.dispose();
        }


6、page_load:页面加载函数,主要是在首次进入页面时,进行初始化,默认的获取所有的信息

复制代码 代码如下:

protected void page_load(object sender, eventargs e)
        {
            if (!ispostback)//首次进行该页时,页面初始化
            {
                recordscount = getrecordscount("default");//默认信息总数
                pagescount = recordscount / pagesize + overpage();//默认的页总数
                viewstate["pagescount"] = recordscount / pagesize - modpage();//保存末页索引,比页总数小1
                viewstate["pageindex"] = 0;//保存页面初始索引从0开始
                viewstate["jumppages"] = pagescount;
                //保存页总数,跳页时判断用户输入数是否超出页码范围
                //显示lbpagecount、lbrecordcount的状态
                lbpagecount.text = pagescount.tostring();
                lbrecordcount.text = recordscount.tostring();
                //判断跳页文本框失效
                if (recordscount <= 10)
                {
                    gotopage.enabled = false;
                }
                    gridviewdatabind("default");//调用数据绑定函数tdatabind()进行数据绑定运算
            }
        }

7、pagerbtncommand_onclick:该方法主要用来处理设计视图页的“首页”、“下一页”,“上一页”,“尾页”,“查询”按钮的click事件,主要通过不同按钮的commandname属性来分别处理,需要在前台为每一个按钮相应的commandname属性赋值,如果用户点击的是“查询”按钮,这个时候需要对查询的sql语句进行重写,加入过滤条件,即用户输入的查询的条件

复制代码 代码如下:

/// <summary>
        /// 页面按钮click处理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void pagerbtncommand_onclick(object sender, eventargs e)
        {
            currentpage = (int)viewstate["pageindex"];
            //从viewstate中读取页码值保存到currentpage变量中进行参数运算
            pages = (int)viewstate["pagescount"];//从viewstate中读取总页参数运算
            button btn = sender as button;
            string sqlresult="default";
            if (btn != null)
            {
                string cmd = btn.commandname;
                switch (cmd)//根据不同的commandname做出不同的处理
                {
                    case "next":
                        currentpage++;
                        break;
                    case "prev":
                        currentpage--;
                        break;
                    case "last":
                        currentpage = pages;
                        break;
                    case "search":
                        if (!string.isnullorempty(searchname.text))
                        {
                            recordscount = getrecordscount("select count(*) from p_user where username like '" + searchname.text + "%'");//获取过滤后的总记录数
                            pagescount = recordscount / pagesize + overpage();//该变量为页总数
                            viewstate["pagescount"] = recordscount / pagesize - modpage();//该变量为末页索引,比页总数小1
                            viewstate["pageindex"] = 0;//保存一个为0的页面索引值到viewstate,页面索引从0开始
                            viewstate["jumppages"] = pagescount;
                            //保存pagecount到viewstate,跳页时判断用户输入数是否超出页码范围
                            //显示lbpagecount、lbrecordcount的状态
                            lbpagecount.text = pagescount.tostring();
                            lbrecordcount.text = recordscount.tostring();
                            //判断跳页文本框失效
                            if (recordscount <= 10)
                                gotopage.enabled = false;
                sqlresult = "select top " + pagesize + "user_serialid,username,displayname,orgcode,orgname from p_user where user_serialid not in(select top " + pagesize * currentpage + " user_serialid from p_user order by user_serialid asc) and username like '" + searchname.text + "%' order by user_serialid asc";
                        }
                        else
                        {
                            response.write("请输入您所要查找的用户姓名!");
                        }
                        break;
                    case "jump":
                       jumppage = (int)viewstate["jumppages"];
                      //从viewstate中读取可用页数值保存到jumppage变量中
                      //判断用户输入值是否超过可用页数范围值
                      if(int32.parse(gotopage.text) > jumppage ||      int32.parse(gotopage.text) <= 0)
response.write("<script>alert('页码范围越界!')</script>");
                      else
                      {
                          int inputpage = int32.parse(gotopage.text.tostring()) - 1;
                          //转换用户输入值保存在int型inputpage变量中
                          viewstate["pageindex"] = inputpage;
                          currentpage = inputpage;
                         //写入inputpage值到viewstate["pageindex"]中
                          sqlresult = "select top " + pagesize + "user_serialid,username,displayname,orgcode,orgname from p_user where user_serialid not in(select top " + pagesize * currentpage + " user_serialid from p_user order by user_serialid asc) and username like '" + searchname.text + "%' order by user_serialid asc";
                      }
                        break;
                    default:
                        currentpage = 0;
                        break;
                }
                viewstate["pageindex"] = currentpage;
                //将运算后的currentpage变量再次保存至viewstate
                gridviewdatabind(sqlresult);//调用数据绑定函数tdatabind()
            }
        }

8、btn_reset_click:该方法主要用来进行重置,用户完成一次查询之后,需要重置,才能进行下一次的查询操作

复制代码 代码如下:

protected void btnreset_click(object sender, eventargs e)
     (
         recordscount = getrecordscount("default");//默认信息总数
         pagescount = recordscount / pagesize + overpage();//默认的页总数
         viewstate["pagescount"] = recordscount / pagesize - modpage();//保存末页索引,比页总数小1
         viewstate["pageindex"] = 0;//保存页面初始索引从0开始
         viewstate["jumppages"] = pagescount;
         //保存页总数,跳页时判断用户输入数是否超出页码范围
         //显示lbpagecount、lbrecordcount的状态
         lbpagecount.text = pagescount.tostring();
         lbrecordcount.text = recordscount.tostring();
         //判断跳页文本框失效
         if (recordscount <= 10)
         {
             gotopage.enabled = false;
         }
             gridviewdatabind("default");//调用数据绑定函数tdatabind()进行数据绑定运算
     }

这里的高效分页方法主要用的是select top 10 id ,name from tb where id not in (select top 10*n from tb order by id asc) order by id asc

示例中的n代表的是页数,之前原子里也有很多关于高效分页的讨论,这里就不再多说了,我个人觉得这个分页语句效果还不错,当然除此之外还有row_number()函数分页、select max() 分页等等方法,之前也有总结过,有兴趣的朋友可以看一下我之前写的listview和repeater高效分页这篇文章,里边讲述的也很详细,只要你一步一步的照着去操练应该问题不大的。

这里需要解释一下的是为什么没有有数据绑定控件直接进行绑定,因为在sharepoint2010项目里边它支持的数据源控件只有xmldatasource,所以就只有自己动手实现了。

好了今天就到这里了,希望能给大家带来些帮助吧!还请多多指教!

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网