嵌套的“;从“;用扩展方法表示的LINQ查询
本文关键字:表示 LINQ 查询 方法 嵌套 扩展 | 更新日期: 2023-09-27 18:22:11
如何使用扩展方法语法编写此LINQ查询?
var query = from a in sequenceA
from b in sequenceB
select ...;
为了您将来的参考,C#规范的7.16节回答了此表单中的所有问题。
以下段落回答了您的具体问题:
带有第二个from
子句和select
子句的查询表达式
from x1 in e1
from x2 in e2
select v
被翻译成
( e1 ) . SelectMany( x1 => e2 , ( x1 , x2 ) => v )
所以你的查询:
var query = from a in sequenceA
from b in sequenceB
select ...;
与相同
var query = ( sequenceA ) . SelectMany( a => sequenceB , ( a , b ) => ... )
(请注意,这当然假设"…"是一个表达式,而不是一个后面跟着查询延续的表达式。)
hdv的回答指出
var query = ( sequenceA ) . SelectMany(
a => ( sequenceB ) . Select( b => ... ) );
也将是逻辑上有效的翻译,尽管它不是我们实际执行的翻译。在LINQ实现的早期,这是我们选择的翻译。然而,当你堆积更多的from
子句时,它会使lambdas嵌套得越来越深,这会给编译器在类型推理中带来巨大的问题。这种翻译的选择会破坏编译器的性能,因此我们引入了透明标识符机制,为我们提供了一种更便宜的方式来表示深度嵌套作用域的语义。
如果您对这些主题感兴趣:
有关为什么深度嵌套的lambda会给编译器带来难以解决的问题的更多想法,请参阅:
http://blogs.msdn.com/b/ericlippert/archive/2007/03/26/lambda-expressions-vs-anonymous-methods-part-four.aspx
http://blogs.msdn.com/b/ericlippert/archive/2007/03/28/lambda-expressions-vs-anonymous-methods-part-five.aspx
有关透明标识符的更多信息,请参阅Wes Dyer的这篇文章,他在C#3.0:中实现了这些标识符
http://blogs.msdn.com/b/wesdyer/archive/2006/12/22/transparent-identifiers.aspx
以及我关于他们的系列文章:
http://ericlippert.com/2014/07/31/transparent-identifiers-part-one/
var query = sequenceA.SelectMany(a => sequenceB.Select(b => ...));
编辑:正如Eric Lippert在评论中指出的,这给出了相同的结果,但故意不是内部翻译的方式。请参阅他的答案,了解调用SelectMany
的另一种方法,该方法与原始方法相对应。此外,为了清楚起见,添加了省略的b =>
。
另一种编写方法是:
var query = a.Join(b, i => new { }, j => new { }, (i, j) => new { i = i, j = j });