OFFSET 和 FETCH NEXT 子句。.NET 数据分页查询

在现代应用程序开发中,数据分页查询是一项至关重要的功能,它不仅能够提升用户体验,还能提高系统性能和稳定性,本文将详细介绍.NET平台上实现数据分页查询的多种方法,并提供相关代码示例。
一、分页查询的原理分析
分页查询的核心原理是在大量数据中,通过某种方式仅检索出用户当前需要查看的部分数据,以减少数据处理量和传输时间,常见的分页方法包括偏移分页(Offset Pagination)和键集分页(Keyset Pagination)。
1. 偏移分页(Offset Pagination)
偏移分页通过指定跳过多少条记录来获取数据,要获取第2页的数据,每页显示10条记录,则跳过前20条记录,然后取接下来的10条记录。
var position = 20; // (page 1) * pageSize
var nextPage = context.Posts
.OrderBy(b => b.PostId)
.Skip(position)
.Take(10)
.ToList();
2. 键集分页(Keyset Pagination)
键集分页通过记住上一次查询的最后一个键值来获取下一页数据,适用于支持随机访问的场景。
var lastId = 55; // 上一页最后一个记录的ID
var nextPage = context.Posts
.OrderBy(b => b.PostId)
.Where(b => b.PostId > lastId)
.Take(10)
.ToList();
二、分页类的设计分析
为了简化分页操作,可以设计一个通用的分页类,封装不变的部分作为方法体,变化的参数通过属性传递。

1. 分页类的属性
PageSize: 每页显示的条数
FiledName: 需要显示的字段名
TableName: 表的名称
Condition: 查询条件
PrimaryKey: 表的主键或唯一键
CurrentPage: 当前页码

Sort: 排序条件
2. 分页类的只读属性
RecordCount: 记录总数(只读)
TotalPage: 总页数(只读)
3. 分页方法的编写
public class SqlDataPager
{
public int PageSize { get; set; }
public string FiledName { get; set; }
public string TableName { get; set; }
public string Condition { get; set; }
public string PrimaryKey { get; set; }
public int CurrentPage { get; set; }
public string Sort { get; set; }
private int recordCount;
public int RecordCount
{
get { return recordCount; }
}
public int TotalPage
{
get { return (int)Math.Ceiling((double)recordCount / PageSize); }
}
// 其他方法和属性...
}
三、使用DeveloperSharp进行分页查询
DeveloperSharp是一个功能强大的工具包,提供了简便的分页方法,以下是如何使用DeveloperSharp进行分页查询的步骤。
1. 引入DeveloperSharp包
在NuGet中引入DeveloperSharp包:
InstallPackage DeveloperSharp.Framework.CoreUtility
2. 创建数据源类
创建一个继承自DeveloperSharp.Structure.Model.DataLayer的数据源类,设置数据库连接字符串:
using DeveloperSharp.Structure.Model; // DataLayer命名空间
using DeveloperSharp.Framework.QueryEngine; // DatabaseType命名空间
namespace YZZ
{
[DataSource(DatabaseType.SQLServer, "Server=localhost;Database=Test;Uid=sa;Pwd=123")]
public class TestData : DeveloperSharp.Structure.Model.DataLayer
{
// 类中没有任何代码
}
}
3. 调用分页方法
在控制台应用类中调用分页方法:
using DeveloperSharp.Extension; // Table扩展所在的命名空间(.NET6/VS2022用户,则需要在.csproj文件中的<ItemGroup>下添加<Using>标签)
class Program
{
static void Main(string[] args)
{
TestData td = new TestData();
var pp = td.PagePartition("select top 5000 * from t_Order where Id>10 order by Id desc", 20, 162);
List<Product> Products = pp.Table.ToList<Product>();
foreach (var P in Products)
{
Console.WriteLine(P.Name);
}
Console.ReadLine();
}
}
四、使用LINQ进行分页查询
LINQ提供了一种简洁的方式来实现分页查询,以下是一个泛型分页查询方法的示例:
public static async Task<(List<T> Data, int TotalCount)> GetPagedAsync<T, TOrderKey>(
this IQueryable<T> query,
Expression<Func<T, TOrderKey>> orderBy,
bool ascending,
int page,
int pageSize
) where T : class
{
if (query == null) throw new ArgumentNullException(nameof(query));
if (orderBy == null) throw new ArgumentNullException(nameof(orderBy));
int totalCount = await query.CountAsync();
query = ascending ? query.OrderBy(orderBy) : query.OrderByDescending(orderBy);
List<T> data = await query.Skip((page 1) * pageSize).Take(pageSize).ToListAsync();
return (data, totalCount);
}
五、常见问题与解答栏目
Q1: 为什么分页查询时需要确保排序的唯一性?
A1: 确保排序的唯一性可以避免在某些情况下跳过或重复记录,如果仅按日期排序,但存在多个相同日期的记录,分页时可能会导致这些记录被跳过或重复显示,建议使用复合索引(如日期和ID组合)来确保排序的唯一性。
Q2: 如何在大数据量下优化分页查询的性能?
A2: 在大数据量下,分页查询的性能可以通过以下方法优化:
1、使用覆盖索引:确保分页查询中的排序字段上有索引,最好是复合索引。
2、避免SELECT:只选择所需的列,减少数据传输量。
3、限制返回记录数:使用TOP子句限制返回的记录数,避免一次性加载过多数据。
4、使用存储过程:对于复杂的分页查询,可以考虑使用存储过程来优化执行计划。
5、异步操作:使用异步操作提高应用程序的响应能力,特别是在处理大量数据时。
来源互联网整合,作者:小编,如若转载,请注明出处:https://www.aiboce.com/ask/72783.html