【问题标题】:NHibernate with linq paging performanceNHibernate 与 linq 分页性能
【发布时间】:2012-11-29 01:09:51
【问题描述】:

我在一个 c# 项目的 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 秒)。Skip(offset).Take(pageSize ).ToList();线。 这是 pageSize = 100 和 offset = 0。

我的理解是,由于延迟执行,SELECT 直到需要时才会发生(在本例中为 .ToList())。此时,它知道它需要哪些行,它应该只选择相关的 100 行。

'data' 有预期的 100 行,但似乎系统已经从数据库中获取了所有 200k 奇数行,然后在代码中完成了分页。

我对 LINQ/NHibernate 的理解不正确吗? 如果是这样,我想我需要用标准 API 做这样的事情:NHibernate Paging performance (Better option)

【问题讨论】:

    标签: c# performance sqlite nhibernate


    【解决方案1】:

    看下面一行:

    IEnumerable<Tobj> result = session.Query<Tobj>().Where(whereClause);
    

    您正在使用IEnumerable&lt;Tobj&gt; 字段,因此当您调用Skip 时,您正在调用Enumerable.Skip 方法。我相信你想要的是Queryable.Skip 方法。

    请尝试以下代码行:

    IQueryable<Tobj> result = session.Query<Tobj>().Where(whereClause);
    

    这将确保调用正确的扩展方法。

    说明

    Enumerable.Skip 方法将遍历源 IEnumerable&lt;Tobj&gt; 中的每个实体,然后才在 N 个元素之后返回结果。这将强制 NHibernate 将所有数据加载到内存中,因为 NHibernate 只知道需要数据。

    Queryable.Skip 方法将改为构建一个表达式树,以便 NHibernate 稍后在访问数据时可以处理这个问题。此时 NHibernate 知道跳过前 N 条记录。

    请注意,我不确定 LINQ 提供程序当前是否支持 SkipTake 方法。

    【讨论】:

    • 啊啊啊啊!谢谢!这很有意义。我进行了更改,现在一切运行良好。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-08
    • 1970-01-01
    • 2010-09-06
    • 1970-01-01
    • 2011-04-06
    相关资源
    最近更新 更多