繁体   English   中英

使用 Linq to Entities 在一次操作中获取 COUNT 和 SKIP TAKE

[英]Getting COUNT and SKIP TAKE in one operation with Linq to Entities

我在 Linq to Entities 支持的数据访问层中有一个数据调用,旨在进行分页调用。

这样做时,我需要选择数据的一个子集,比如 50 行,但还要获取所有匹配项的计数,以了解有多少总匹配项需要分页。

目前,我正在执行以下操作:

var queryResult = DatabaseContext.Table
    .Where(x => !x.IsDeleted)
    .Where(p => (
            p.PropertyOne.ToLower().Contains(query) ||
            p.PropertyTwo.ToLower().Contains(query) 
            ));

int count = queryResult.Count();

var returnData = queryResult
    .OrderBy(i => i.ID)
    .Skip(start).Take((length))
    .Select(y => new ObjectDTO
    {
        PropertyOne = y.PropertyOne,
        PropertyTwo = y.PropertyTwo
    }
    .AsEnumerable();

这会导致两个代价高昂的数据库操作。 由于某种原因, COUNT操作实际上比SELECT操作花费的时间更长。

有没有办法在同一操作中获取计数和子集?

对我来说,逻辑流程表明我们执行以下操作:

  • 看表
  • 在表中查找符合条件的项目
  • 获取所有匹配项的计数
  • 返回匹配的编号子集

这在一次操作中似乎是可能的,但我不知道如何。

尝试一,慢

尝试了 D Stanley 将完整结果集转换为List并在分页中进行计数和内存的建议,但它的速度大约慢了 2 倍(平均 6.9 秒 vs 平均 3.9 秒)

值得一提的是,该数据集大约有 25,000 条记录,在 JOIN 中搜索了十几个相关表。

这可能是可能的,但由于您使用的标准,它可能不会更快。 由于您要在列值中搜索文本,因此不能使用索引,因此必须进行表扫描。 可以执行单个查询来获取所有记录并在 linq-to-objects 中执行CountSkip/Take

var queryResult = DatabaseContext.Table
    .Where(x => !x.IsDeleted)
    .OrderBy(i => i.ID)
    .Where(p => (
            p.PropertyOne.ToLower().Contains(query) ||
            p.PropertyTwo.ToLower().Contains(query) 
            ))
    .ToList();

int count = queryResult.Count();  // now this will be a linq-to-objects query

var returnData = queryResult
    .Skip(start).Take((length))
    .AsEnumerable();

但是您必须尝试一下,看看它是否会更快。

像这样的东西怎么样:

db.Products
   .Take(10)
   .Select(p => new 
                {
                    Total = db.Products.Count, 
                    Product = p
                })

如果这不好,了解在 SQL 中使用 OVER() 获得总结果和其中一页可能会有所帮助。

暂无
暂无

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

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