【问题标题】:Does an expression enumerate parameters when executed in LINQ?在 LINQ 中执行时,表达式是否枚举参数?
【发布时间】:2013-09-26 20:06:56
【问题描述】:

我有一个使用 LINQ 返回 IQueryable 的方法

 return eventFacade.GetNewBuildingEvents()
                .Where(EventPredicates.IsBuildingOwner(
                       memberFacade.GetFriendsAndColleagues(m).Select(y => y.Id))
        )

GetFriendsAndColleagues(m).Select(y => y.Id) 返回一个 IEnumerable

        public static Expression<Func<Event, bool>> IsBuildingOwner(IEnumerable<int> friendids)
    {
        return
            x =>
                x.Building.BuildingMembers.Where(k => k.Type == MemberType.Owner)
                    .Any(p => friendids.Contains(p.Member.Id));
    }

总的来说,我仍在学习 LINQ 和 C#。我知道IQueryableIEnumerable 延迟执行,我知道IQueryable 过滤发生在数据库中,而IEnumerable 发生在内存中。

我还知道,在迭代集合的情况下,最好枚举集合,这样每次迭代都不会调用数据库。

所以当我的最终查询被执行时,传递给我的表达式的IEnumerable 是否会被枚举一次,然后用于比较GetNewBuildingEvents() 返回的每个项目

是否在每次比较时调用数据库以获取列表?

【问题讨论】:

  • GetNewBuildingEvents的实现和返回类型是什么?什么是 IQueryable 提供程序?无论如何,我相信或者它的 LINQ-to-entities 或 IQueryable 会抛出异常。
  • 我在查询中使用 .AsEnumerable() 并稍后在方法中将其转换为另一个对象。上面编写的查询编译并运行良好
  • 您是在专门询问 Linq to SQL / DB 对吗?因为 AFAIK 您可以将 IQueryable 和 IEnumerable 用于 LINQ to Objects 以及 Linq to DB。最终实际运行的内容取决于 LINQ 提供程序。
  • 只需将分析器附加到您的 SQL 并查看正在发送的确切查询。如果您(和/或您的数据库管理员)对结果查询感到满意,那么就接受它们。如果没有,您可以开始考虑优化它们。
  • @MattFoxxDuncan 重点是看这段 C# 代码生成的 SQL 查询,而不是看它运行了多长时间。这将帮助您确定哪些操作已成功映射到 SQL,以及哪些操作映射到 SQL 效率低下或根本没有映射到 SQL 并在客户端完成。

标签: c# .net linq


【解决方案1】:

如果您想知道它迭代了多少次,只需在一个序列上运行该代码,该序列在迭代时会执行一些可观察到的副作用,这样您就可以看到它发生了多少次。

您可以使用以下辅助方法将任何序列包装成一个序列,每次迭代时都会将其写入控制台。

public static IEnumerable<T> NoisyWrapper<T>(IEnumerable<T> source)
{
    Console.WriteLine("Rabble rabble rabble!!!");
    foreach (var item in source)
        yield return item;
}

这样就解决了一般情况下的问题。

在特定情况下,序列应该只迭代一次。您正在创建一个编译成数据库查询并在数据库端执行的表达式。将IEnumerable 中的Contains 与大多数基于SQL 的查询提供程序一起在适当的上下文(您的上下文)中使用将被转换为SQL 中的IN 子句。 IEnumerable 将需要迭代一次以提供 IN 子句的值,并且不需要多次迭代。

【讨论】:

  • 太棒了!谢谢,这正是我正在寻找的解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-24
  • 1970-01-01
  • 2013-05-02
相关资源
最近更新 更多