linq到sql语法不同但应该得到相同的结果

Ben*_*ler 2 c# linq linq-to-sql

我正在玩表达树和各种Linq语法.我写了以下内容:

using (NorthwindDataContext DB = new NorthwindDataContext())
        {
            DataLoadOptions dlo = new DataLoadOptions();

            // Version 1
            dlo.AssociateWith<Customer>(c => c.Orders.Where(o => o.OrderID < 10700).Select(o => o)); 

            // Version 2
            dlo.AssociateWith<Customer>(c => from o in c.Orders
                                             where o.OrderID < 10700
                                             select o);
        }
Run Code Online (Sandbox Code Playgroud)

版本1方法返回错误,指出"子查询中不支持运算符'选择'."

虽然版本2运行得很好.根据我的理解,我写的是完全相同的东西,但一个是"点"符号语法,另一个是查询表达式语法.

我在这里错过了什么吗?为什么错误在一个而不是另一个"if"它们实际上是同一个查询?

Dan*_*ite 7

.Select(o => o)的查询中不需要.


Jon*_*eet 7

为了扩展Daniel的答案,它select o被称为简并查询表达式 - 它被C#编译器删除.所以你的查询被翻译成:

c.Orders.Where(o => o.OrderID < 10700)
Run Code Online (Sandbox Code Playgroud)

注意,如果没有where条款,然而,编译器仍然包括Select调用,因此:

from o in c.Orders
select o
Run Code Online (Sandbox Code Playgroud)

被翻译成

c.Orders.Select(o => o)
Run Code Online (Sandbox Code Playgroud)

从语言规范的第7.15.2.3节开始:

简并查询表达式是一种简单地选择源元素的表达式.翻译的后期阶段通过用其源替换它们来移除由其他翻译步骤引入的退化查询.但是,确保查询表达式的结果永远不是源对象本身是很重要的,因为这会向查询客户端显示源的类型和标识.因此,此步骤通过显式调用源来保护直接在源代码中编写的简并查询Select.然后由实现者Select 和其他查询运算符来确保这些方法永远不会返回源对象本身.