导读:在上篇文章中,介绍了用假分页实现数据的分页显示 ,而避免了去拖动滚动条。但,假分页在分页的同时,其实是拖垮了查询效率的。每一次分页都得重新查询一遍数据,那么有没有方法可以同时兼顾效率和分页呢,那就是真分页。
一、真分页概述
相对于假分页,真分页是什么呢?
真分页就是每次换页的时候,只查询相对应的页码的那几条数据。比如说,每页显示5条数据,那么窗体加载的时候,就只是查询了符合条件的前5条数据。如果点击第10页,那么查询的就是第46条数据至第50条数据。这样,每次打开一页的速度是一样的,而且效率会很高。因为每次查询的数据是很小、有限的。
二、实现真分页
2.1,添加控件
在实现假分页的过程中,需要用到第三方控件AspNetPager。需要先下载这个控件的DLL文件,然后拖动至工具箱中,然后再在界面中使用它。
2.2,界面设计
备注:分页控件的显示风格和形式,可以由用户自己确定。
2.3,代码实现
<span style="font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:24px;">using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Data.SqlClient; using System.Data; namespace WebApplication1 { public partial class truePage : System.Web.UI.Page { /// <summary> /// 窗体加载时,没有改变页数的数据显示 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack ) { //窗体打卡时,起始数据编号为0,终止数据编号为每页的信息条数 int intStartIndex = ANP.PageSize * 0; int intEndIndex = ANP.PageSize * 1; <span style="color:#ff0000;"><strong> ANP.RecordCount = MyAllData().Rows.Count;</strong></span> //绑定数据 GridView1.DataSource = MyPartData(intStartIndex, intEndIndex); GridView1.DataBind(); } } /// <summary> /// 改变了页数的数据显示 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void ANP_PageChanged(object sender, EventArgs e) { //起始数据编号=每页的信息容量*(当前页数-1)+1; //例:第六页,每页显示5条,第六页的起始数据=5*5+1=26; int intStartIndex=ANP.PageSize * (ANP.CurrentPageIndex-1)+1; int intEndIndex = ANP.PageSize * ANP.CurrentPageIndex; GridView1.DataSource = MyPartData(intStartIndex,intEndIndex ); GridView1.DataBind(); } /// <summary> /// 分页查询 /// </summary> /// <param name="intStartIndex">开始的数据编号</param> /// <param name="intEndIndex">结束的数据编号</param> /// <returns>表格</returns> private static DataTable MyPartData(int intStartIndex,int intEndIndex) { SqlConnection con = new SqlConnection("server=.;database=newssystem;uid=sa;password=123456"); con.Open(); string strCmd = "Proc_TruePage";//存储过程 SqlParameter[] paras = new SqlParameter[] { new SqlParameter ("@intStartIndex",intStartIndex), new SqlParameter ("@intEndIndex",intEndIndex) }; SqlCommand cmd = new SqlCommand(strCmd ,con ); cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.AddRange(paras); SqlDataReader sdr = cmd.ExecuteReader(); DataTable dt = new DataTable(); dt.Load(sdr); con.Close(); return dt; } /// <summary> /// 全部查询 /// </summary> /// <returns></returns> private static DataTable MyAllData() { SqlConnection con = new SqlConnection("server=.;database=newssystem;uid=sa;password=123456"); con.Open(); string strCmd = "select * from comment"; SqlCommand cmd = new SqlCommand(strCmd, con); SqlDataReader sdr = cmd.ExecuteReader(); DataTable dt = new DataTable(); dt.Load(sdr); con.Close(); return dt; } } }</span></span>
2.4,存储过程
<span style="font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:24px;">USE [newssystem] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ============================================= -- Author: <HHX> -- Create date: <2015/5/9> -- Description: <通过行号的确立,实现分页查询数据> -- ============================================= ALTER PROCEDURE [dbo].[Proc_TruePage ] @intStartIndex int,--开始的页 @intEndIndex int--结束的页 as BEGIN SET NOCOUNT ON; --为获取到行号的表建立一个临时表 with TempTable as ( select ROW_NUMBER () over(order by id desc) as RowsIndex,* from comment ) --查询从开始页到结束页的数据 select * from TempTable where RowsIndex between @intStartIndex and @intEndIndex ; END </span></span>
说明:在实现真分页的时候,也查询了一遍整个数据,目的是为了获取总共有多少条数据。不过,它只通篇查询了一遍数据库,相对于假分页来说,也是够效率的。但考虑到数据量大的话,真的也能让人等一会儿了。所以,可以通过减少查询字段,或者说依靠行号来解决。
2.5,实现效果
三、个人感受
只要不满足于现象,也就是不将就,就能找到更好的。学习了也有一段时间了,也该关心关心性能了,只是实现了功能还是不够的。