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

时间:2015-03-23 18:54:30

标签: c# sql-server linq entity-framework entity-framework-6

我在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秒和平均3.9秒)

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

1 个答案:

答案 0 :(得分:0)

这可能是可能的,但由于您使用的标准,它可能不会快得多。由于您在列值中搜索文本,因此无法使用索引,因此必须执行表扫描。您可以执行单个查询以获取所有记录,并在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();

但是你必须尝试看它是否会更快。