4

我正在尝试通过实体数据模型从具有大约 2000 万个条目的 MS SQL 数据库中的表中获取每条记录。我最初的想法是按块检索数据,如下所示:

public IEnumerable<IEnumerable<device>> GetDevicesInChunks(int chunkSize)
{
    using (var db = new AccountsEntities())
    {
        for (int i = 0; i < db.devices.Count(); i += chunkSize)
        {
            yield return db.devices.Skip(i).Take(chunkSize);
        }
    }
}

但是,从我使用上述方法时抛出的异常来看,我似乎必须在调用OrderBy之前调用Skip

The method 'Skip' is only supported for sorted input in LINQ to Entities. The method 
'OrderBy' must be called before the method 'Skip'.

我确信调用OrderBy我检索到的每个记录子集都会很昂贵,因为这些设备没有特定的顺序 - 我觉得我在这里走错了路。

通过 LINQ 处理大型 SQL 查询的最佳方法是什么?

4

2 回答 2

4

发生错误是因为方法 Skip 需要在 OrderBy 之后运行。如果没有 OrderBy,您将无法运行 Skip。方法Skip需要知道第一个取什么,如果你放什么是第一个需要知道select的顺序来知道第一个是从头到尾还是从尾到头的那个数字。

你可以在这里阅读更多

因此,您的代码如下所示:

public IEnumerable<IEnumerable<device>> GetDevicesInChunks(int chunkSize)
{
    using (var db = new AccountsEntities())
    {
        for (int i = 0; i < db.devices.Count(); i += chunkSize)
        {
            yield return db.devices.OrderByDescending(y => y).Skip(i).Take(chunkSize);
        }
    }
}

如果您认为这是一个繁重的查询,请记住 Entity Framework 可以缓存查询和数据。如果您不喜欢该方法的 sql,您可以手动运行查询

个人经验: 我将它与具有 2 bi 行的数据库一起使用,并且......它并不慢。但我的表中有索引,我总是使用缓存。

更多信息: 如果您愿意,可以使用程序。在这里查看更多

于 2013-03-07T00:05:50.760 回答
-1

您可能不必执行 an OrderBy- 您可能只需要在执行Skipand之前填充列表Take。我认为您可以使用 a.Count()来填充查询,之后您可以使用Skipand Take

于 2013-03-07T00:18:09.187 回答