繁体   English   中英

使用LINQ有效地分页大型数据集

[英]Efficiently paging large data sets with LINQ

在研究使用C#(使用LINQ)实现分页的最佳方法时,大多数建议如下:

// Execute the query
var query = db.Entity.Where(e => e.Something == something);

// Get the total num records
var total = query.Count();

// Page the results
var paged = query.Skip((pageNum - 1) * pageSize).Take(pageSize);

这似乎是通常建议的策略(简化)。

对我来说,分页的主要目的是提高效率。 如果我的表包含120万条其中某物==的记录,则我不想同时检索所有记录。 相反,我想分页数据,抓取尽可能少的记录。 但是用这种方法,似乎这是一个有争议的问题。

如果我理解正确,则第一条语句仍在检索120万条记录, 然后将在必要时分页。

以这种方式分页是否真的可以提高性能? 如果要每次检索120万条记录,那又有什么意义(除了明显的UI好处之外)?

我误会吗? 是否有任何.NET专家可以教我有关LINQ,分页和性能的知识(在处理大型数据集时)?

第一条语句不执行实际的SQL查询,它仅构建您要运行的查询的一部分。

当您调用query.Count() ,第一个将被执行

SELECT COUNT(*) FROM Table WHERE Something = something

query.Skip().Take()也不会执行查询,只有当您尝试枚举结果(对paged进行foreach调用或调用.ToList() )时,它将执行适当的SQL语句仅检索页面的行(使用ROW_NUMBER)。

如果在SQL事件探查器中观察到此情况,您将看到恰好执行了两个查询,并且它绝不会尝试检索完整表。


要小心,当您使用调试器,因为如果你的第一条语句后退一步,尝试看看的内容query ,将执行SQL查询。 也许这就是您误会的根源。

// Execute the query
var query = db.Entity.Where(e => e.Something == something);

仅供参考,在第一条语句之后什么都没有调用

// Get the total num records
var total = query.Count();

此计数查询将转换为SQL,并将调用数据库。 此调用不会获取所有记录,因为生成的SQL如下所示:

SELECT COUNT(*) FROM Entity where Something LIKE 'something'

对于最后一个查询, 它也不会获取所有记录 该查询将转换为SQL,并且分页在数据库中运行。

也许您会发现这个问题有用: 实现分页的有效方法

我相信实体框架可以根据linq语句以适当的条件构造SQL查询。 (例如,使用ROWNUMBER()OVER ...)。

但是,我对此可能是错的。 我将运行SQL事件探查器,并查看生成的查询是什么样的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM