ASP .NET 如何在 SQL 查询层面实现分页 1
【编者按】本文作者为来自巴基斯坦的软件开发工程师 Aqeeel,主要介绍了在 SQL 查询层面实现 ASP.NET 应用的分页方法。
本文系 OneAPM 工程师编译呈现,以下为正文。
GridView 提供了一种实现分页的方法。但是,随着记录的不断扩大,我们需要在查询层面进行优化。
简介
在 SQL 查询层面实现 ASP.NET 程序分页,而不借助 GridView。
背景
无可否认,GridView 是在 ASP.NET Web 表单展示数据的强大工具,它能在结果集较大时实现分页。然而,后端会获取完整的数据,抽取出相关数据,然后通过 GridView 展示在 Web 表单中。在这种情况下,相关数据只是完全抽取数据的一小部分。这些多余的数据造成了处理能力、内存空间以及时间的极大浪费。在本文中,我们将展示如何仅从数据库抽取所需数据,从而避免这些浪费。
下图展示了从数据库中获取完整数据的方式。在渲染阶段,相关数据会被抽取出来,填充到 GridView 中。
下图展示了从数据库中抽取过滤或相关数据的方式,进而得到更小的数据集。在 Web 应用中,同样的数据集无需经过进一步抽取,就可以填充到 GridView 中。
具体实现
工具
本例借助 SQL Server 2014 与 Visual Studio 2015 实现。2012 之前的 SQL Server 版本不支持 FETCH,但是使用 ROW NUMBER 可以达到同样的效果。
首先进行后端设置:
创建名为 TestPagingInASPNET 的数据库,
创建名为 AdministrativeUnits 与 Cities 的两张表。
创建存储过程(Stored Procedures,简称 SP),用于从数据库获取数据。请注意,笔者创建了两个存储过程,名字分别为 SelectCitiesWithPaging 与 SelectCitiesWithPagingOldSQLVersions。由于笔者是在 SQL Server 2014 中实现该解决方案的,在第一个 SP 中,笔者使用了 OFFSET FETCH 声明。对于更早的版本,比如 SQL Server 2005 与 SQL Server 2008,则应该使用 ROW_NUMBER() 函数而非 OFFSET FETCH。因此,请创建与开发环境相适合的 SP。与传统的 SP 不同,此处创建的 SP 将包含三个参数,细节如下:
@PageNumber 为将会返回的页码数(Page Number)
@RowsPerPage 为每页的行数(Number of Rows)
@TotalResords(输出参数)为总的记录
-- CREATE DATABASE
CREATE DATABASE TestPagingInASPNET;
GO-- CREATE FIRST TABLE
CREATE TABLE AdministrativeUnits (AdministrativeUnitID INT PRIMARY KEY IDENTITY(1, 1),Name VARCHAR(50)
);
GO-- CREATE SECOND TABLE
CREATE TABLE Cities (CityID INT PRIMARY KEY IDENTITY(1, 1),AdministrativeUnitID INT,Name VARCHAR(50)
);
GO-- CREATE THE STORED PROCEDURE
CREATE PROCEDURE SelectCitiesWithPaging@PageNumber INT,@RowsPerPage INT,@TotalRows INT OUTPUT
AS
BEGINSET NOCOUNT ON;SELECT @TotalRows = COUNT(*)FROM [AdministrativeUnits] [AU]INNER JOIN [Cities] [C] ON [AU].[AdministrativeUnitID] = [C].[AdministrativeUnitID]SELECT [AU].[Name] [Administrative Unit],[C].[Name] [City]FROM [AdministrativeUnits] [AU]INNER JOIN [Cities] [C] ON [AU].[AdministrativeUnitID] = [C].[AdministrativeUnitID]ORDER BY [AU].[Name], [C].[Name]OFFSET ((@PageNumber - 1) * @RowsPerPage) ROWS FETCH NEXT @RowsPerPage ROWS ONLYEND
GO-- CREATE THE STORED PROCEDURE
CREATE PROCEDURE SelectCitiesWithPagingOldSQLVersions@PageNumber INT,@RowsPerPage INT,@TotalRows INT OUTPUT
AS
BEGINSET NOCOUNT ON;SELECT @TotalRows = COUNT(*)FROM [AdministrativeUnits] [AU]INNER JOIN [Cities] [C] ON [AU].[AdministrativeUnitID] = [C].[AdministrativeUnitID]SELECT *FROM ( SELECT ROW_NUMBER() OVER (ORDER BY [AU].[Name], [C].[Name]) NUMBER,[AU].[Name] [Administrative Unit],[C].[Name] [City]FROM [AdministrativeUnits] [AU]INNER JOIN [Cities] [C] ON [AU].[AdministrativeUnitID] = [C].[AdministrativeUnitID]) tblWHERE Number BETWEEN ((@PageNumber - 1) * @RowsPerPage + 1) AND (@PageNumber * @RowsPerPage)
END
GO
现在,讨论应用的前端部分
ASPX
在 Web 表单中绘制一个表格,其包含两个表格行(Table Rows)
在第一个表格行中推拽下放一个 GridView。此处无需启用分页,因为存储过程实现该功能。
在第二个表格行中,放置两个按钮来实现前页与后页之间的跳转。此外,为两个按钮创建点击事件。
在第三个表格行中,放置页面导航链接。
在下面;提供了 .aspx 文件中的代码。
<table style="width:100%;"><tr><td><asp:GridView ID="GridView1" runat="server"></asp:GridView></td></tr><tr><td style="text-align:center;"><asp:Button ID="btnGridViewPrevious" runat="server" OnClick="btnGridViewPrevious_Click" Text="<" /><asp:TextBox ID="txtGridViewPageNumber" runat="server"></asp:TextBox><asp:Button ID="btnGridViewGoToPageNumber" runat="server" Text="Go to Page" OnClick="btnGridViewGoToPageNumber_Click" /><asp:Button ID="btnGridViewNext" runat="server" OnClick="btnGridViewNext_Click" Text=">" /></td></tr><tr><td style="text-align:center;" runat="server" id="tdPage"></td></tr></table>
ASPX.cs
在 .aspx.cs 文件中,我们会创建两个函数。
GetAndBindData()
第一个函数将得到来自数据库的请求数据。请注意,我们以页码数与每页的行数为参数。
接收到的数据将填充在网格中。
在页面加载(Page Load)事件触发,且参数页面数(PageNumber)为1时,即会调用该函数。
CreatePager()
第二个函数将创建用于导航的链接。
private void GetAndBindData(Int32 PageNumber, Int32 RowsPerPage)
{SqlConnection con = new SqlConnection(ConnectionString);SqlCommand cmd = new SqlCommand();cmd.CommandType = System.Data.CommandType.StoredProcedure;cmd.CommandText = "SelectProjects";cmd.Connection = con;SqlParameter par1 = new SqlParameter();par1.ParameterName = "PageNumber";par1.DbType = System.Data.DbType.Int32;par1.Direction = System.Data.ParameterDirection.Input;par1.Value = PageNumber;cmd.Parameters.Add(par1);SqlParameter par2 = new SqlParameter();par2.ParameterName = "RowsPerPage";par2.DbType = System.Data.DbType.Int32;par2.Direction = System.Data.ParameterDirection.Input;par2.Value = RowsPerPage;cmd.Parameters.Add(par2);SqlParameter par3 = new SqlParameter();par3.ParameterName = "TotalRows";par3.DbType = System.Data.DbType.Int32;par3.Direction = System.Data.ParameterDirection.Output;cmd.Parameters.Add(par3);SqlDataAdapter adp = new SqlDataAdapter();adp.SelectCommand = cmd;DataSet ds = new DataSet();con.Open();adp.Fill(ds);Session["TotalRows"] = par3.Value.ToString();GridView1.DataSource = ds.Tables[0];GridView1.DataBind();
}private void CreatePager(Int32 TotalRecords, Int32 PageNumber, Int32 RowsPerPage)
{Int32 intIndex;Int32 intPageNumber;tdPage.InnerHtml = "";intPageNumber = 1;for (intIndex = 1; intIndex <= TotalRecords; intIndex+=10){tdPage.InnerHtml += " <a href=''>" + intPageNumber.ToString() + "</a> ";intPageNumber++;}if (TotalRecords > intIndex) {tdPage.InnerHtml += " <a href=''>" + intIndex.ToString() + "</a> ";}
}protected void btnGridViewNext_Click(object sender, EventArgs e)
{Int32 NewPageNumber = Convert.ToInt32(Session["PageNumber"]);NewPageNumber++;Session["PageNumber"] = NewPageNumber;txtGridViewPageNumber.Text = Session["PageNumber"].ToString();GetAndBindData(Convert.ToInt32(Session["PageNumber"]), 10);btnGridViewPrevious.Enabled = true;
}protected void btnGridViewGoToPageNumber_Click(object sender, EventArgs e)
{Int32 NewPageNumber = Convert.ToInt32(txtGridViewPageNumber.Text);Session["PageNumber"] = NewPageNumber;txtGridViewPageNumber.Text = Session["PageNumber"].ToString();GetAndBindData(Convert.ToInt32(Session["PageNumber"]), 10);btnGridViewPrevious.Enabled = true;
}
要点总结
通过此方法,在用户改变页面索引时,开发者可以只获取相关数据进行展示,而非完整的数据集。这样,不仅可以从数据库中选出相关数据,在 GridView 中过滤数据所需的步骤也可以避免。从而切实提高并优化应用性能。
原文地址:http://www.codeproject.com/Articles/1078...
OneAPM 助您轻松锁定 .NET 应用性能瓶颈,通过强大的 Trace 记录逐层分析,直至锁定行级问题代码。以用户角度展示系统响应速度,以地域和浏览器维度统计用户使用情况。想技术文章,请访问 OneAPM 官方博客。
本文转自 OneAPM 官方博客
ASP .NET 如何在 SQL 查询层面实现分页 1相关推荐
- ASP .NET 如何在 SQL 查询层面实现分页
[编者按]本文作者为来自巴基斯坦的软件开发工程师 Aqeeel,主要介绍了在 SQL 查询层面实现 ASP.NET 应用的分页方法. 本文系 OneAPM 工程师编译呈现,以下为正文. GridVie ...
- oracle查数据存入数组,如何在SQL查询中使用Oracle关联数组
ODP.Net公开了将关联数组作为参数从C#传递到Oracle存储过程的能力.除非您尝试在sql查询中使用该关联数组中包含的数据,否则它是一个很好的功能. 原因是它需要上下文切换 – SQL语句需要S ...
- 代码日常--如何在SQL查询语句中添加判断逻辑
前景提要:查询某个商品是否参加推广,表product_channel,字段distribute_status. Y表示参与,N表示不参与,但由于该字段是新添加,默认为null,所以null也属于不参与 ...
- 如何在SQL Server查询语句(Select)中检索存储过程(Store Procedure)的结果集
如何在SQL Server查询语句(Select)中检索存储过程(Store Procedure)的结果集?(2006-12-14 09:25:36) 与这个问题具有相同性质的其他描述还包括: 如 ...
- 用于存储过程的ASP.NET Core Blazor和EF Core原始SQL查询
目录 介绍 背景 先决条件 使用代码 创建数据库和表 步骤1:创建ASP.NET Core Blazor服务器应用程序 运行测试应用程序 步骤2:安装软件包 连接字符串 步骤3:建立模型类 创建DBC ...
- oracle中begin end的作用,如何在SQL * Plus中使用begin/end运行Oracle查询?
我已经用begin/end创建了一个查询块,并且想要在SQL * Plus中运行它.但是我怎样才能在命令行中运行它?如何在SQL * Plus中使用begin/end运行Oracle查询? 其实代码来 ...
- asp mysql datetime_ASP中SQL和Access数据库中时间/日期字段内容查询的方法说明
方法如下: MS SQL数据库: SQL="select * from 表名 where 时间/日期字段 between '"& 传递过来开始的时间值 &" ...
- asp sql查询过滤空格_对比Excel,轻松学习SQL数据分析数据笔记02
本文主要梳理<对比Excel,轻松学习SQL数据分析>对于自己有用的sql知识.这本书中的所有代码和函数均适用于my sql 8.0版本. SQL的基本功能数据定义(DDL)--对数据库, ...
- sql查询禁用缓存_如何在SQL Server 2017中启用和禁用身份缓存
sql查询禁用缓存 Every data warehouse developer is likely to appreciate the significance of having surrogat ...
最新文章
- 利用脑机接口提高意念打字速度,让新手用户也能快速上手意念交流
- “毕设导师互选系统”项目产品宣传推广方案
- oracle中用START WITH...CONNECT BY PRIOR子句实现递归查询
- FullCalendar插件月视图正常显示周视图不正常显示问题解决方法
- C Primer Plus 第8章 字符输入/输出和输入确认 8.1 单字符I/O
- 内存cookie与持久cookie
- Emmet 快速编写html代码
- STM32工作笔记0094---音乐播放器实验
- Json-lib, 实现Java对象与JSON数据格式的互转
- g++是什么_路由器信号分为2.4G和5G,有什么区别?怎么选?
- Spring AOP(二)之AfterReturning增强处理
- 高通工具QXDM、QCAT和QPST
- 电脑外接显示器或ipad分屏
- 计算机上没有端口DOT4,hp1010win7系统打印机装不了dot4端口没反应
- android 实现拍照,android 实现拍照的2种方法
- 移动端适配多种方案详细分析
- 神经网络图像细节分析,神经网络 图像相似度
- 干货满满!25种绝佳VSCode扩展,体验便捷高效的生活
- PHP项目快速接入微信功能
- python常用字体显示方框_seaborn模块中,图表中文字体变成方块的问题如何解决?...
热门文章
- 米家扫地机器人是石头代工_扫地机器人“两强”突进,选科沃斯还是石头科技?...
- C++socket编程(七):7.3 http的响应协议
- oracle session status killed,进程状态为KILLED的进程如何杀掉
- 原子变量的原理与应用
- linux网卡ip自动启动不了怎么办,Linux杂谈:解决配置静态ip后eth0网卡启动不了的问题...
- python 多进程 内存增长_python 多进程 内存 copy-on-write
- python 脚本传参
- opencv 图像属性
- 机器学习实战(MachineLearinginAction) 第二章 k-近邻算法
- git 理解 HEAD^与HEAD~