8

我在生成的部分类上有一个方法,如下所示:

var pChildren = this.Children
    .Skip(skipRelated)
    .Take(takeRelated)
    .ToList();

当我查看我的 SQL Server 时,我可以看到生成的代码正在执行SELECT *.* FROM Children此代码直接取自我的课程,我已验证我的 Skip/Take 的顺序在我的 .ToList 之前。

如果我删除 .ToList,那条线很快(并且没有 SQL 发送到我的数据库),但是当我尝试foreach覆盖结果时,我得到相同的 SQL 发送到我的数据库:SELECT *.* FROM Children.

使用 .Skip 和 .Take来处理我的实体的导航属性时,我需要做些什么特别的事情吗?

更新

我将尝试生成实际的 SQL,我目前还没有为此设置。我找到了第一个,因为它出现在 SSMS 的“最近昂贵的查询”列表中。

运行这个:

var pChildren = this.Children
    //.Skip(skipRelated)
    //.Take(takeRelated)
    .ToList();

返回约 4,000,000 行,耗时约 25 秒。

运行这个:

var pChildren = this.Children
    //.Skip(skipRelated)
    .Take(takeRelated)
    .ToList();

返回约 4,000,000 行,耗时约 25 秒。

正如我所说,我将获取为这些生成的 SQL 并将它们摆出来。

4

2 回答 2

7

问题是当您查询这样的子集合时,您正在执行 LINQ-to-Object 查询。EF 将加载整个集合并在内存中执行查询。

如果您使用的是 EF 4,您可以像这样查询

var pChildren = this.Children.CreateSourceQuery()
                 .OrderBy(/* */).Skip(skipRelated).Take(takeRelated);

在 EF 4.1 中

var pChildren = context.Entry(this)
                   .Collection(e => e.Children)
                   .Query()
                   .OrderBy(/* */).Skip(skipRelated).Take(takeRelated)
                   .Load();
于 2011-12-29T00:04:12.547 回答
1

如果您调用Skip的结果有帮助Take吗?IE

table.Take(takeCount+skipCount).Skip(skipCount).ToList()

另见

于 2011-12-28T23:36:27.427 回答