【发布时间】: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#。我知道IQueryable 和IEnumerable 延迟执行,我知道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 并在客户端完成。