简体   繁体   English

嵌套“来自”LINQ查询用扩展方法表示

[英]Nested “from” LINQ query expressed with extension methods

How can I write this LINQ query by using the extension method syntax? 如何使用扩展方法语法编写此LINQ查询?

var query = from a in sequenceA
            from b in sequenceB
            select ...; 

For your future reference, all questions of this form are answered by section 7.16 of the C# specification. 为了您将来的参考,本表格中的所有问题均由C#规范的第7.16节回答。

Your specific question is answered by this paragraph: 本段回答您的具体问题:


A query expression with a second from clause followed by a select clause 带有第二个from子句后跟select子句的查询表达式

from x1 in e1
from x2 in e2
select v

is translated into 被翻译成

( e1 ) . SelectMany( x1 => e2 , ( x1 , x2 ) => v )

So your query: 所以你的查询:

var query = from a in sequenceA            
            from b in sequenceB
            select ...;  

Is the same as 是相同的

var query =  ( sequenceA ) . SelectMany( a => sequenceB , ( a , b ) => ... )

(Note that of course this assumes that the "..." is an expression, and not, say, an expression followed by a query continuation.) (注意,当然这假设“...”是表达式,而不是表示后跟查询延续的表达式。)

hdv's answer points out that hdv的答案指出了这一点

var query =  ( sequenceA ) . SelectMany( 
    a => ( sequenceB ) . Select( b => ... ) );

would also be a logically valid translation, though it is not the translation we actually perform. 也可能是一个逻辑上有效的翻译,虽然它不是我们实际执行的翻译。 In the early days of LINQ implementation, this was the translation we chose. 在LINQ实施的早期,这是我们选择的翻译。 However, as you pile on more from clauses, it makes the lambdas nest more and more deeply, which then presents the compiler with an enormous problem in type inference. 但是,当你from子句中堆积更多内容from ,它会使lambdas嵌套越来越深,这会给编译器带来类型推断中的巨大问题。 This choice of translation wrecks compiler performance, so we introduced the transparent identifier mechanism to give us a much cheaper way to represent the seamntics of deeply nested scopes. 这种翻译选择破坏了编译器的性能,因此我们引入了透明的标识符机制,为我们提供了一种更便宜的方式来表示深度嵌套的范围的sentics。

If these subjects interest you: 如果这些科目对您感兴趣:

For more thoughts on why deeply nested lambdas present a hard problem for the compiler to solve, see: 有关为什么深层嵌套的lambdas为编译器提出难题的更多想法,请参阅:

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/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 http://blogs.msdn.com/b/ericlippert/archive/2007/03/28/lambda-expressions-vs-anonymous-methods-part-five.aspx

For more information about transparent identifiers, see this post from Wes Dyer, who implemented them in C# 3.0: 有关透明标识符的更多信息,请参阅Wes Dyer的这篇文章,他在C#3.0中实现了它们:

http://blogs.msdn.com/b/wesdyer/archive/2006/12/22/transparent-identifiers.aspx http://blogs.msdn.com/b/wesdyer/archive/2006/12/22/transparent-identifiers.aspx

And my series of articles about them: 我的一系列关于它们的文章:

http://ericlippert.com/2014/07/31/transparent-identifiers-part-one/ http://ericlippert.com/2014/07/31/transparent-identifiers-part-one/

var query = sequenceA.SelectMany(a => sequenceB.Select(b => ...));

Edit : as pointed out by Eric Lippert in the comments, this gives the same results, but is intentionally not how it is translated internally. 编辑 :正如Eric Lippert在评论中所指出的,这给出了相同的结果,但故意不是如何在内部翻译。 See his answer for another way to call SelectMany , which does correspond to the original. 请参阅他的答案,了解另一种调用SelectMany ,它与原始方式相对应。 Also, added the omitted b => for clarity. 另外,为了清楚起见,添加了省略的b =>

写它的另一种方法是:

var query = a.Join(b, i => new { }, j => new { }, (i, j) => new { i = i, j = j });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM