使用LINQ处理大型SQL查询

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

public IEnumerable<IEnumerable> 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); } } } 

但是,看来我必须在调用Skip之前调用OrderBy ,从我使用上述方法时抛出的exception来判断

 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查询的最佳方法是什么?

发生错误是因为Skip需要在OrderBy之后运行。 没有OrderBy,您无法运行Skip。 Skip方法需要知道第一个要采用的方法,如果你把第一个需要知道的东西放在select的顺序上,知道第一个是从开始到结束或结束到开头的那个数字。

你可以在这里阅读更多

所以,你的代码看起来像这样:

 public IEnumerable> 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个双线的数据库……它并不慢。 但我在我的表中有索引,我总是使用缓存。

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

您可能不必执行OrderBy – 您可能只需要在执行Skip and Take之前填充列表。 我认为您可以使用.Count()填充查询,之后您可以使用SkipTake