我知道下一个查询会引发异常,因为IQueryable<>
提供程序不支持Enumerable.TakeWhile
扩展方法。
IQueryable<Contact> search = context.Contacts.TakeWhile(q => q.ContactID > 10);
foreach(var q in search); // exception
但是,如果我尝试从 C# 的角度理解前面的查询,就会感到困惑。
由于要在上面的链中调用的最后一个 Linq 方法是Linq-to-Objects TakeWhile
,我希望search
变量是 type IEnumerable<T>
,但它是 IQueryable 类型(我知道IQueryable<T>
查询被转换为表达式树,而Linq-to-对象查询本质上转换为延迟方法调用,因此尝试将表达式树(由创建context.Contacts
)转换为方法调用是行不通的。如前所述,从 C# 的角度来看,这让我感到困惑)。
此外,Queryable
运算符构建查询的方式是调用 on IQueryProvider<T>.CreateQuery
,给定表达式树构建新IQueryable<T>
对象。这是否意味着IEnumerable<T>.TakeWhile
操作员必须知道以某种方式自己构建表达式树(它不知道)或必须能够调用IQueryProvider<T>.CreateQuery
?
我很确定我的假设是错误的,所以有人可以解释一下前面的查询如何能够返回 type 的结果IQueryable<T>
而不是IEnumerable<T>
?
先感谢您