.Net下的高效分页

打印 上一主题 下一主题

主题 914|帖子 914|积分 2742

本文技术方案支持.Net/.Net Core/.Net Framework
 数据分页,几乎是任何应用系统的必备功能。但当数据量较大时,分页操作的效率就会变得很低。大数据量分页时,一个操作耗时5秒、10秒、甚至更长时间都是有可能的,但这在用户使用的角度是不可接受的……
 
数据分页往往有三种常用方案。
第一种,把数据库中存放的相关数据,全部读入代码/内存,再由代码对其进行分页操作。
第二种,直接在数据库中对相关数据进行分页操作,再把分页后的数据输出给代码程序。
第三种,先把数据库中的相关数据全部读入“缓存”,再由代码程序对“缓存”中的数据进行读取+分页操作。
 
本文下面重点阐述第一种与第二种两个解决方案,它们也都是直接基于“数据库”的。
(第三种方案虽然速度较快,但由于需要用到“缓存”这类第三方工具,且在有数据更改时需要较复杂的“数据库-缓存”同步操作,故本文暂不详述。)
 
◆◆第一种方案如下◆◆
从NuGet引入DeveloperSharp包,初始化IUtility工具
  1. using DeveloperSharp.Framework.CoreUtility;
  2. --------------------------
  3. IUtility IU = new Utility();
复制代码
IUtility内构建有3个重载的分页PagePartition方法:
  1. PagePartition
  2. 声明:PagePiece PagePartition(DataTable Table, int PageSize, int PageIndex)
  3. 用途:分页功能
  4. 参数:(1)DataTable Table   --  需要分页的DataTable
  5.      (2)int PageSize  --  页面大小
  6.      (3)int PageIndex    --  当前页码
  7. 返回:PagePiece   --  页片实体
  8. PagePartition
  9. 声明:PagePiece<List<T>> PagePartition<T>(IQueryable<T> DataList, int pageSize, int pageIndex) where T : class
  10. 用途:分页功能
  11. 参数:(1)IQueryable<T> DataList   --  需要分页的IQueryable
  12.      (2)int PageSize  --  页面大小
  13.      (3)int PageIndex    --  当前页码
  14. 返回:PagePiece   --  页片实体
  15. PagePartition
  16. 声明:PagePiece<List<T>> PagePartition<T>(List<T> DataList, int pageSize, int pageIndex) where T : class
  17. 用途:分页功能
  18. 参数:(1)List<T> DataList   --  需要分页的List
  19.      (2)int PageSize  --  页面大小
  20.      (3)int PageIndex    --  当前页码
  21. 返回:PagePiece   --  页片实体
复制代码
 
分页方法的返回值PagePiece/PagePiece类,包含分页后的数据集、总页数、总数据、当前页码、等等一系列“分页”后经常会用到的数据。PagePiece/PagePiece的属性的详细说明如下:
  1. PageSize
  2. 声明:public int PageSize;
  3. 用途:int --页面大小
  4. TotalPageNumber
  5. 声明:public int TotalPageNumber;
  6. 用途:int --总页数
  7. TotalRecordNumber
  8. 声明:public int TotalRecordNumber;
  9. 用途:int --记录总数
  10. CurrentStartIndex
  11. 声明:public int CurrentStartIndex;
  12. 用途:int --当前页的记录起始编号
  13. CurrentEndIndex
  14. 声明:public int CurrentEndIndex;
  15. 用途:int --当前页的记录结束编号
  16. CurrentPageSize
  17. 声明:public int CurrentPageSize;
  18. 用途:int --当前页的记录数量
  19. CurrentPageIndex
  20. 声明:public int CurrentPageIndex;
  21. 用途:int --当前页码
  22. Table
  23. 声明:public System.Data.DataTable Table;
  24. 用途:System.Data.DataTable--当前页的数据表
  25. (或者)
  26. DataList
  27. 声明:public List<T> DataList;
  28. 用途:List<T>--当前页的数据
复制代码
 
 
◆◆第二种方案如下◆◆
为了演示“第二种分页方案”如何使用,我们首先在Visual Studio中新建一个控制台工程。然后,我们做如下三个操作。
【第一步】:从NuGet引用DeveloperSharp包。
【第二步】:创建一个用来与数据库进行通信的“数据源类”(文本示例为:TestData.cs),内容如下:
  1. using DeveloperSharp.Structure.Model;//DataSource的命名空间
  2. using DeveloperSharp.Framework.QueryEngine;//DatabaseType的命名空间
  3. namespace YZZ
  4. {
  5.     [DataSource(DatabaseType.SQLServer, "Server=localhost;Database=Test;Uid=sa;Pwd=123")]
  6.     public class TestData : DeveloperSharp.Structure.Model.DataLayer
  7.     {
  8.         //类中没有任何代码
  9.     }
  10. }
复制代码
说 明 :“数据源类”(文本示例为:TestData.cs)必 须 继 承 自 DeveloperSharp.Structure.Model.DataLayer 类 , 并 且 在 其 上 设 置DataSource属 性 的 初 始 化 值 为“数据库类型”及其“链接字符串”。

 
【第三步】:为控制台应用类,添加通过“数据源类”(TestData)调用其PagePartition方法进行数据分页的代码。注 意:核心代码就一行而已!!
代码如下:
  1. using DeveloperSharp.Extension;//Table扩展所在的命名空间(.NET6/VS2022用户,则需要在.csproj文件中的<ItemGroup>下添加<Using>标签)
  2. -----------------------------
  3.     class Program
  4.     {
  5.         static void Main(string[] args)
  6.         {
  7.             TestData td = new TestData();
  8.             //分页
  9.             var pp = td.PagePartition("select top 5000 * from t_Order where Id>10 order by Id desc", 20, 162);
  10.             List<Product> Products = pp.Table.ToList<Product>();
  11.             foreach (var P in Products)
  12.             {
  13.                 Console.WriteLine(P.Name);
  14.             }
  15.             Console.ReadLine();
  16.         }
  17.     }
复制代码
Product类代码如下:
  1.     public class Product
  2.     {
  3.         public string Id { get; set; }
  4.         public string Name { get; set; }
  5.         public int Quantity { get; set; }
  6.     }
复制代码
 
此处的PagePartition方法有两个重载方法,其详细功能说明如下:
  1. PagePartition
  2. 声明:public PagePiece PagePartition(string RecordSet, string Id, int PageSize, int PageIndex)
  3. 用途:分页功能(有主键)
  4. 参数:(1)string RecordSet     --需要分页的记录集,可以是表、视图、或者SQL语句
  5. (2)string Id     --主键
  6. (3)int PageSize     --页面大小
  7. (4)int PageIndex     --当前页码
  8. 返回:PagePiece  --页片实体
  9. PagePartition
  10. 声明:public PagePiece PagePartition(string RecordSet, int PageSize, int PageIndex)
  11. 用途:分页功能(无主键)
  12. 参数:(1)string RecordSet     -- 需要分页的记录集,可以是表、视图、或者SQL语句
  13.      (2)int PageSize    --页面大小
  14. (3)int PageIndex    --当前页码
  15. 返回:PagePiece  --页片实体
复制代码
注意:
(1)     当你需要分页的数据表有“主键”字段时,使用“分页功能(有主键)”。反之,使用“分页功能(无主键)”。
(2)     RecordSet是你需要分页的“数据总集”的SQL语句。该SQL语句的形式丰富多样,可以带条件、排序、甚至还能是多表的联合查询、等。
 
【附注】:文中所有示例均已成功运行通过!!技术交流/支持,请微信扫描二维码,备注“进群”!


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

慢吞云雾缓吐愁

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表