[英]Nested “from” LINQ query expressed with extension methods
如何使用扩展方法语法编写此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
子句中堆积更多内容from
,它会使lambdas嵌套越来越深,这会给编译器带来类型推断中的巨大问题。 这种翻译选择破坏了编译器的性能,因此我们引入了透明的标识符机制,为我们提供了一种更便宜的方式来表示深度嵌套的范围的sentics。
如果这些科目对您感兴趣:
有关为什么深层嵌套的lambdas为编译器提出难题的更多想法,请参阅:
有关透明标识符的更多信息,请参阅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 });
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.