[英]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.