C# linq到sql语法不同,但应得到相同的结果
我在玩表达式树和各种Linq语法。我写了以下内容:C# linq到sql语法不同,但应得到相同的结果,c#,linq,linq-to-sql,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
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);
}
使用(NorthwindDataContext DB=new NorthwindDataContext())
{
DataLoadOptions dlo=新的DataLoadOptions();
//版本1
dlo.AssociateWith(c=>c.Orders.Where(o=>o.OrderID<10700)。选择(o=>o));
//版本2
dlo.AssociateWith(c=>从c.订单中的o开始)
其中o.OrderID<10700
选择o);
}
Version 1方法返回一个错误,说明“子查询中不支持运算符'Select'
而版本2运行得很好。据我所知,我写的是完全相同的东西,但一个是“点”符号语法,另一个是查询表达式语法
我是不是遗漏了什么?为什么一个错误而另一个错误“如果”它们实际上是同一个查询 您不需要
。在查询中选择(o=>o)
。要扩展Daniel的答案,Select o
被称为退化查询表达式,它被C编译器删除。因此,您的查询被转换为:
c.Orders.Where(o => o.OrderID < 10700)
翻译成
c.Orders.Select(o => o)
根据语言规范第7.15.2.3节:
退化查询表达式是一个
它可以轻松地选择
消息来源。第二阶段
转换删除退化查询
由其他翻译步骤引入
用源代码替换它们。
然而,重要的是确保
查询表达式的结果是
永远不要使用源对象本身,因为
这将揭示类型和类型
客户端的源的标识
查询的最后一步。因此这一步
保护已写入的退化查询
直接在源代码中通过显式
调用在源上选择。它是
然后由的实施者选择
和其他查询运算符以确保
这些方法永远不会返回
源对象本身
感谢这两个答案和伟大的解释乔恩。
c.Orders.Select(o => o)