Nested “from” query LINQ espressa con metodi di estensione

Come posso scrivere questa query LINQ utilizzando la syntax del metodo di estensione?

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

Per riferimento futuro, tutte le domande di questo modulo sono risolte dalla sezione 7.16 della specifica C #.

La tua domanda specifica è risolta da questo paragrafo:


Un’espressione di query con una seconda clausola seguita da una clausola select

 from x1 in e1 from x2 in e2 select v 

è tradotto in

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

Quindi la tua domanda:

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

Equivale a

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

(Si noti che naturalmente ciò presuppone che “…” sia un’espressione e non, diciamo, un’espressione seguita da una continuazione della query.)

la risposta di hdv lo sottolinea

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

sarebbe anche una traduzione logicamente valida, anche se non è la traduzione che effettivamente eseguiamo. Nei primi giorni di implementazione LINQ, questa era la traduzione che abbiamo scelto. Tuttavia, mentre ci si accumula di più from clausole, fa sì che i lambdas nidificano sempre più profondamente, il che presenta al compilatore un enorme problema di inferenza del tipo. Questa scelta della traduzione distrugge le prestazioni del compilatore, quindi abbiamo introdotto il meccanismo dell’identificatore trasparente per darci un modo molto più economico di rappresentare gli aspetti siderurgici degli ambiti profondamente annidati.

Se questi argomenti ti interessano:

Per ulteriori riflessioni sul perché i lambda profondamente annidati presentano un problema difficile da risolvere per il compilatore, vedere:

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

Per ulteriori informazioni sugli identificatori trasparenti, vedere questo post di Wes Dyer, che li ha implementati in C # 3.0:

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

E la mia serie di articoli su di loro:

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

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

Modifica : come indicato da Eric Lippert nei commenti, questo dà gli stessi risultati, ma non è intenzionalmente come viene tradotto internamente. Vedi la sua risposta per un altro modo di chiamare SelectMany , che corrisponde all’originale. Inoltre, ha aggiunto l’omesso b => per chiarezza.

Un altro modo per scriverlo sarebbe:

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