Raymond Raymond

[ASP.NET]强类型DataSet + ObjectDataSource + GridView + Access数据库 百万级数据实现高性能分页

event 2010-11-18 visibility 800 comment 0 insights toc
more_vert
insights Stats
[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>

之所以删除参数是因为这两个跟分页相关的参数不需要在这里设置,否则获取方法时会出错。

页面运行效果如下:



可见我们的分页效果已经达到了

More from Kontext
comment Comments
No comments yet.

Please log in or register to comment.

account_circle Log in person_add Register

Log in with external accounts