我知道下一个查询会引发异常,因为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>?
先感谢您