LINQ表达式如何知道Where()出现在Select()之前?

Den*_*sen 9 .net c# linq

我正在尝试创建一个LINQ提供程序.我正在使用指南LINQ:构建一个IQueryable提供程序系列,我已经将代码添加到LINQ:构建一个IQueryable提供程序 - 第四部分.

我正在感受它是如何工作的以及它背后的想法.现在我遇到了一个问题,这不是代码问题,而是关于理解的问题.

我正在解雇这个声明:

QueryProvider provider = new DbQueryProvider();
Query<Customer> customers = new Query<Customer>(provider);

int i = 3;
var newLinqCustomer = customers.Select(c => new { c.Id, c.Name}).Where(p => p.Id == 2 | p.Id == i).ToList();
Run Code Online (Sandbox Code Playgroud)

不知何故,代码或表达式知道它Where来自之前Select.但是如何以及在哪里?

在代码中没有办法对表达式进行排序,实际上ToString()在调试模式下,表明Select出现在Where.

我试图让代码失败.正常我做了Where第一个,然后是Select.

那么表达式如何排序呢?我没有对指南中的代码进行任何更改.

Stu*_*art 10

表达式是"解释","翻译"或为了你写他们"执行" -所以Where没有之前来Select


如果你执行:

        var newLinqCustomer = customers.Select(c => new { c.Id, c.Name})
                                       .Where(p => p.Id == 2 | p.Id == i).ToList();
Run Code Online (Sandbox Code Playgroud)

然后,Where被在执行IEnumerableIQueryable匿名类型.


如果你执行:

        var newLinqCustomer = customers.Where(p => p.Id == 2 | p.Id == i)
                                       .Select(c => new { c.Id, c.Name}).ToList();
Run Code Online (Sandbox Code Playgroud)

然后Where是在执行IEnumerableIQueryable客户类型的.


我唯一能想到的是,你可能会看到一些生成的SQL,其中SELECT和WHERE已被重新排序?在这种情况下,我猜想在(例如)LINQ to SQL提供程序中的某个地方有一个优化步骤,它将接收SELECT Id, Name FROM (SELECT Id, Name FROM Customer WHERE Id=2 || Id=@i)并转换为SELECT Id, Name FROM Customer WHERE Id=2 || Id=@i- 但这必须是提供者特定的优化.