我在 ac# 项目中的 SQLite DB 上使用 NHibernate。我有一个通用的批量数据处理方法,如下所示:
private void DataProcess<Tobj>(int pageSize, Expression<Func<Tobj, bool>> whereClause,
Action<Tobj, ISession> dataProcessingCallback) where Tobj : IModelBase
{
int offset = 0;
bool moreToGet = true;
while (moreToGet)
{
DataAccess((ISession session) =>
{
IEnumerable<Tobj> result = session.Query<Tobj>().Where(whereClause);
List<Tobj> data = result.Skip(offset)
.Take(pageSize)
.ToList();
foreach (Tobj item in data) { dataProcessingCallback(item, session); }
if (data.Count == pageSize) { offset += pageSize; }
else { moreToGet = false; }
});
}
}
(DataAccess 方法为我们提供了可以使用的会话对象、处理事务等)
环顾四周,这似乎与大多数其他 linq 分页实现非常相似。他们通常会做一个 .Skip().Take()
我的问题是,对于大型数据集(在我正在查看的测试用例中,大约有 200k 行),它需要 AGES(在调试器中大约 20 秒)来执行 result.Skip(offset).Take(pageSize).ToList (); 线。这是 pageSize = 100 和 offset = 0。
我的理解是,由于延迟执行,SELECT 直到需要时才会发生(在本例中为 .ToList())。此时,它知道它需要哪些行,它应该只选择相关的 100 行。
'data' 有预期的 100 行,但似乎系统已经从数据库中获取了所有 200k 奇数行,然后在代码中完成了分页。
我对 LINQ/NHibernate 的理解不正确吗?如果是这样,我想我需要使用标准 API 执行类似的操作:NHibernate Paging performance (Better option)