科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道应用软件创建用于ASP.NET的分页控件

创建用于ASP.NET的分页控件

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

解决向任何ASP.NET控件添加分页功能的问题。为开发复合ASP.NET控件提供了很多有用的提示和技巧。

作者:佚名 来源:Microsoft 2007年10月17日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
分页引擎

  SqlPager 控件支持两种检索数据的方法 - 缓存和非缓存。如果采用前者,选择命令原样执行,整个结果集将绑定到在内部进行分页的数据源对象上。PagedDataSource 对象将自动返回适合特定页面的记录。PagedDataSource 类也是在 DataGrid 默认分页机制背后运行的系统组件。

  检索所有记录但只显示适合页面的几个记录,这通常不是一种明智的方法。由于 Web 应用程序的无状态特性,事实上,每次请求页面时都可能运行大量的查询。要使操作有效,采用缓存的数据检索方法必须依赖于某种缓存对象,ASP.NET 的 Cache 对象就是一个很好的候选对象。缓存技术的使用加快了应用程序的运行速度,但其提供的数据快照不能反映最新的更改。另外,它需要使用 Web 服务器上的较多内存。而且荒谬的是,如果大量的数据按会话缓存的话,甚至可能造成很大的问题。Cache 容器对于应用程序来说是全局的;如果数据按会话存储在其中,还需生成会话特有的项目名称。

  Cache 对象的上面是完全支持过期策略的。换句话说,存储在缓存中的数据在一段时间后可以自动被释放。以下代码说明 SqlPager 类中用来获取数据并将其存储在缓存中的一个 private 方法。

private void FetchAllData()
{
 // 在 ASP.NET Cache 中查找数据
 DataTable data;
 data = (DataTable) Page.Cache[CacheKeyName];
 if (data == null)
 {
  // 使用 order-by 信息修改 SelectCommand
  AdjustSelectCommand(true);

  // 如果数据过期或从未被获取,则转到数据库
  SqlDataAdapter adapter = new SqlDataAdapter(SelectCommand, ConnectionString);
  data = new DataTable();
  adapter.Fill(data);
  Page.Cache.Insert(CacheKeyName, data, null,
  DateTime.Now.AddSeconds(CacheDuration),
  System.Web.Caching.Cache.NoSlidingExpiration);
 }

 // 配置分页的数据源组件
 if (_dataSource == null)
  _dataSource = new PagedDataSource();
  _dataSource.DataSource = data.DefaultView;
  _dataSource.AllowPaging = true;
  _dataSource.PageSize = ItemsPerPage;
  TotalPages = _dataSource.PageCount;

 // 确保页面索引有效
 ValidatePageIndex();
 if (CurrentPageIndex == -1)
 {
  _dataSource = null;
  return;
 }

 // 选择要查看的页面
 _dataSource.CurrentPageIndex = CurrentPageIndex;
}

  控件和请求的缓存项目名称是唯一的。它包括页面的 URL 和控件的 ID。在指定的时间(以秒计算)内,数据被绑定到缓存。要使项目过期,必须使用 Cache.Insert 方法。以下较简单的代码将项目添加到缓存,但不包括任何过期策略。

Page.Cache[CacheKeyName] = data;

  PagedDataSource 对象通过其 DataSource 属性获取要进行分页的数据。值得注意的是,PagedDataSource 类的 DataSource 属性只接受 IEnumerable 对象。DataTable 不满足此要求,这就是为什么采取 DefaultView 属性的原因。

  SelectCommand 属性确定在 SQL Server 数据库上运行的查询。此字符串最好为 SELECT-FROM-WHERE 形式。不支持 ORDER BY 子句,如果指定了该子句,将被删除。这正是 AdjustSelectCommand 方法所做的。使用 SortField 属性可以指定任何排序信息。AdjustSelectCommand 方法本身将根据 SortField 的值添加一个正确的 ORDER BY 子句。这样做有什么原因吗?

  当分页程序以 NonCached 模式工作时,原始的查询将被修改以确保只检索当前页面的记录。在 SQL Server 上执行的实际查询文本将采取以下形式。

SELECT * FROM
(SELECT TOP ItemsPerPage * FROM
(SELECT TOP ItemsPerPage*CurrentPageIndex * FROM
(SelectCommand) AS t0
ORDER BY SortField ASC) AS t1
ORDER BY SortField DESC) AS t2
ORDER BY SortField

  该查询弥补了 SQL Server 2000 中 ROWNUM 子句的缺陷,并且对记录进行重新排序,使得只有 x 项目的“第 n 个”块经过正确排序后返回。您可以指定基础查询,分页程序将它分解为多个较小的页面。只有适合某个页面的记录被返回。正如您看到的那样,除了查询命令以外,上述查询需要处理排序字段。这就是为什么另外添加了 SortField 属性。此代码的唯一缺陷是默认情况为升序排序。通过使 ASC/DESC 关键字参数化,可以使此代码真的非常完美:

private void FetchPageData()
{
 // 需要经过验证的页面索引来获取数据。
 // 还需要实际的页数来验证页面索引。
 AdjustSelectCommand(false);
 VirtualRecordCount countInfo = CalculateVirtualRecordCount();
 TotalPages = countInfo.PageCount;

 // 验证页码(确保 CurrentPageIndex 有效或为“-1”)
 ValidatePageIndex();
 if (CurrentPageIndex == -1)
  return;

 // 准备并运行命令
 SqlCommand cmd = PrepareCommand(countInfo);
 if (cmd == null)
  return;
 SqlDataAdapter adapter = new SqlDataAdapter(cmd);
 DataTable data = new DataTable();
 adapter.Fill(data);

 // 配置分页的数据源组件
 if (_dataSource == null)
  _dataSource = new PagedDataSource();
  _dataSource.AllowCustomPaging = true;
  _dataSource.AllowPaging = true;
  _dataSource.CurrentPageIndex = 0;
  _dataSource.PageSize = ItemsPerPage;
  _dataSource.VirtualCount = countInfo.RecordCount;
  _dataSource.DataSource = data.DefaultView;
}

  在 NonCached 模式中,PagedDataSource 对象并不提供整个数据源,因此不能计算出要进行分页的总页数。进而必须对 AllowCustomPaging 属性进行标记,并提供数据源中的实际记录数量。通常,实际数量是使用 SELECT COUNT(*) 查询进行检索的。此模型与 DataGrid 的自定义分页几乎相同。此外,PagedDataSource 对象中选择的当前页面索引通常为 0,因为实际上已经存储了一页记录。

  SqlPager 控件的实现方法就介绍到这里,下面我们介绍一下它的使用方法。
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章