.Skip()。entity framework上的Take()导航属性正在我的SQL Server上执行SELECT *

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

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

当我查看我的SQL Server时,我可以看到生成的代码正在执行SELECT *.* FROM Children此代码直接从我的类中获取,我已经validation了我的Skip / Take的顺序是在我的.ToList之前。

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

使用.Skip和。在我的实体的导航属性上有什么特别的东西需要做吗?

更新

我将尝试获取实际生成的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并将它们构建起来。

问题是,当您查询类似的子集合时,您正在执行LINQ到对象查询。 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(); 

如果你在Take的结果上调用Skip帮助吗? 即

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

另外,请参阅

  • TOP / LIMIT支持LINQ?