我正在玩表达树和各种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);
}
版本1方法返回错误,指出“子查询中不支持运算符'选择'。”
虽然版本2运行得很好。根据我的理解,我写的是完全相同的东西,但一个是“dot”符号语法,另一个是查询表达式语法。
我在这里遗漏了什么吗?为什么错误在一个而不是另一个“if”它们实际上是同一个查询?
答案 0 :(得分:7)
您的查询中不需要.Select(o => o)
。
答案 1 :(得分:7)
为了扩展Daniel的答案,select o
被称为简并查询表达式 - 它被C#编译器删除。所以你的查询被翻译成:
c.Orders.Where(o => o.OrderID < 10700)
请注意,如果没有where
子句,编译器 仍会包含Select
调用,因此:
from o in c.Orders
select o
被翻译为
c.Orders.Select(o => o)
来自语言规范的第7.15.2.3节:
简并查询表达式是一个 那简单地选择了。的元素 来源。后期的 翻译删除退化查询 由其他翻译步骤介绍 用它们的来源替换它们。 但重要的是确保这一点 查询表达式的结果是 永远不是源对象本身,如 这将揭示类型和 客户端的身份 的查询。因此这一步 保护写入的简并查询 直接在源代码中显式 在源上调用
Select
。它是 然后到Select
的实施者 和其他查询运算符来确保 这些方法永远不会返回 源对象本身。