. skip (). take()在实体框架导航属性上执行SELECT *在我的SQL Server上

本文关键字:SELECT 我的 执行 SQL Server 导航 take 实体 框架 skip 属性 | 更新日期: 2023-09-27 18:18:54

我有一个方法在我生成的部分类,像这样:

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

当我查看我的SQL Server时,我可以看到生成的代码正在做SELECT *.* FROM Children。这段代码直接从我的类中获取,我已经验证了我的Skip/Take的顺序是在我的。tolist之前。

如果我删除。tolist,那一行很快(并且没有SQL发送到我的DB),但是当我尝试对结果进行foreach时,我得到相同的SQL发送到我的DB: 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并将它们放置起来。

. skip (). take()在实体框架导航属性上执行SELECT *在我的SQL Server上

问题是,当您查询这样的子集合时,您正在执行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();

如果您在Take的结果上调用Skip是否有帮助?例如

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

,看

  • 对LINQ的TOP/LIMIT支持?