【问题标题】:Force an IQueryable to execute?强制执行 IQueryable?
【发布时间】:2010-10-22 00:35:59
【问题描述】:

我想在 IQueryable 上执行一个“没有 SQL 转换”的方法,有没有办法强制 IQueryable 执行而不必将其存储在某个中间类中?

【问题讨论】:

  • 这是一个盲目的猜测,但如果 string.IsNullOrEmpty 是罪魁祸首,则使用 2 where 子句代替: .Where(o => o.Name != null).Where(o => o.Name .Length > 0).

标签: linq iqueryable delayed-execution


【解决方案1】:
List<Employees> myEmployees =  myqueryable.ToList();

然后你就可以在那个 List 上做你的 linq 了。

【讨论】:

    【解决方案2】:

    当您编写了一个 LinqToSql 不知道如何翻译成 SQL 的查询时,您会收到该消息(这也是它所说的)。

    我不确定我是否完全了解您的要求,但据我所知,您有以下选择:

    1. 重写您的查询,以便 LinqToSql 可以翻译它
    2. 在 Sql Server 上尽可能多地执行查询,然后在内存中执行其余的(使用 linq to objects)
    3. 坐下来哭

    假设我们排除 #3,让我们看看其他 2 个示例。

    1. 重写它 - 为了解决这个问题,我们需要您的 linq 查询。

    2. 在这里,您从初始查询中取出无法翻译的部分,然后在您的 Iqueryable 调用 ToList 上,然后在该列表上应用查询的其余部分。

    您可以执行查询而无需存储它吗?好吧,并非如此,您可以始终循环遍历结果,因此不要将其存储在变量中,但显然查询的结果需要存储在某个地方。

    【讨论】:

    • 不需要坐下来哭。
    • 非常真实——但是我觉得没有人应该站着哭。如果你必须哭,你需要正确地哭。
    【解决方案3】:

    问题是您希望您的方法在本地执行而不是在数据库中执行吗?如果是这样,AsEnumerable 就是你的朋友。这是一个非常简单的方法,例如:

    public IEnumerable<T> AsEnumerable(IEnumerable<T> source)
    {
        return source;
    }
    

    重要的是它使结果的编译时类型为IEnumerable&lt;T&gt; 而不是IQueryable&lt;T&gt;,这意味着您之后调用的任何LINQ 查询运算符都将是LINQ to Objects 而不是LINQ to SQL。

    例如:

    var query = context.Employees
                       // Filtering performed in SQL
                       .Where(emp => emp.IsFullTime)
                       .AsEnumerable()
                       // Projection performed locally; ComputeSalary has no
                       // SQL equivalent
                       .Select(emp => new { Employee = emp,
                                            Salary = ComputeSalary(emp) });
    

    您可以按照其他地方的建议调用 ToList,但如果您正在执行过滤并且真的不需要内存中的 完整 列表,请调用 AsEnumerable 并过滤 /em> 结果会比先加载所有内容更有效率。

    【讨论】:

    • 这种技术是否也适用于 Linq to EF?好像没有。
    • 我不明白“在本地执行而不是在数据库中执行”是什么意思。对于像我这样的人: IQueryable as = from a in x select a;然后 a.Count(); a.Foreach(...) 将执行两个 SQL 查询。
    • @Tymek:是的,执行两个 SQL 查询。但是“在本地执行”是指“从数据库中获取查询中的所有结果,然后在内存中执行其余的查询”——因此您可以执行不适用于 SQL 的过滤、投影等。
    • @Jon - 现在明白了。我认为一个例子是必须的。嗯...我太蹩脚了,还没有编辑权限。你认为你可以添加一个例子,比如 IQueryable as = (from a in x select a).AsEnumerable().Where( o => o.Name != null); vs. IQueryable as = (from a in x select a).Where( o => o.Name != null);只是说在一种情况下 sql 将有 where 子句,而另一种则没有?
    • @Tymek:我认为有一个您确实无法在 SQL 中执行查询的示例会更合适。将添加一个。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-12
    相关资源
    最近更新 更多