[ASP.NET]强类型DataSet + ObjectDataSource + GridView + Access数据库 百万级数据实现高性能分页
本文讲述如何在GridView中实现高性能的分页;之所以会提出这样的问题,是因为在上一篇文章中的ObjectDataSource+强类型DataSet+GridView,无论页面每一页显示多少条数据,数据表中的所有数据都会加载到内存中,如果数据达到百万级、千万级以上,这样的分页的性能我们可想而知。
在SQL Server中我们可以借助于Row_Number() over (order by NoteID desc)
来实现分页存储过程,并与ObjectDataSource以及强类型DataSet结合,实现高性能的分页,这样可以保证,每次仅查询出一页数据,而不会占用太多的内存。之前看到一些朋友提到GridView中的分页是鸡肋,其实不然,我们可以自定义分页提高性能。
关于GridView高性能分页,ASP.NET官方网站上已有一篇比较好的实例文章(SQL Server数据库):Efficiently Paging Through Large Amounts of Data,为了帮助大家更方便的理解,我结合之前的例子,在Access数据库实现高性能的分页。
一,Access分页查询语句
在Access数据库中没有存储过程的支持,因此我们没有办法按照SQL Server的方式来进行分页查询,一般情况使用下面的句式:
SELECT TOP 页大小 * FROM 表 WHERE (ID NOT IN (SELECT TOP (页大小*(页数-1)) id FROM 表 ORDER BY id)) ORDER BY ID
二,在强类型的DataSet中添加ObjectDataSource分页需要的SelectCountMethod属性需要的方法
在NotesData中添加一个查询:
单击下一步->完成创建,即可看到我们新的查询:
按照上面步骤添加查询:
我们暂且设置SQL为:
点击下一步->完成创建。
四,修改在Access数据库中分页查询的方法
由于Access数据库在一些方面使用不如SQL Server那样强大,因此这里需要我们自己进行改造,我们对自动生成的NotesTableAdapter类的方法GetNotesPaged进行重载,我们查看其源代码为:
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] [global::System.ComponentModel.Design.HelpKeywordAttribute("vs.data.TableAdapter")] [global::System.ComponentModel.DataObjectMethodAttribute(global::System.ComponentModel.DataObjectMethodType.Select, false)] public virtual NotesData.NotesDataTable GetNotesPaged() { this.Adapter.SelectCommand = this.CommandCollection[2];
NotesData.NotesDataTable dataTable = new NotesData.NotesDataTable(); this.Adapter.Fill(dataTable); return dataTable; }
在DAL下新加类NotesTableAdapter的partial class,代码如下:
using System; using System.Collections.Generic; using System.Web;
namespace DataAccessingSample.DAL.NotesDataTableAdapters
{ public partial class NotesTableAdapter { /// <summary> /// 分页查询数据的方法,其参数分别对应ObjectDataSource的分页相关属性 /// </summary> /// <param name="startRowIndex"></param> /// <param name="maximumRows"></param> /// <returns></returns> [global::System.ComponentModel.DataObjectMethodAttribute(global::System.ComponentModel.DataObjectMethodType.Select, false)] public virtual NotesData.NotesDataTable GetNotesPaged(int startRowIndex, int maximumRows) { this.Adapter.SelectCommand = this.CommandCollection[2]; this.Adapter.SelectCommand.CommandText = string.Format(@"SELECT TOP {0} NoteID, NoteTitle, NoteContent, AddDateTime, NoteUser FROM Notes WHERE NoteID > ?", maximumRows); this.Adapter.SelectCommand.Parameters.Clear(); this.Adapter.SelectCommand.Parameters.Add("@NoteID", System.Data.OleDb.OleDbType.Integer).Value = startRowIndex+1; NotesData.NotesDataTable dataTable = new NotesData.NotesDataTable(); this.Adapter.Fill(dataTable); return dataTable; } } }
五,重新设置ObjectDataSource
生成解决方案,然后配置ObjectDataSource,更改其Select方法,并且设置其SelectCountMethod属性:
设置其属性:
修改控件的标记内容,将
<SelectParameters> <asp:Parameter Name="startRowIndex" Type="Int32" /> <asp:Parameter Name="maximumRows" Type="Int32" /> </SelectParameters>
修改
<SelectParameters> </SelectParameters>
之所以删除参数是因为这两个跟分页相关的参数不需要在这里设置,否则获取方法时会出错。
页面运行效果如下:
可见我们的分页效果已经达到了