Can these two LINQ queries be used interchangeably?

a) Do the following two queries get the same results:

var query1 = collection_1 .SelectMany(c_1 => c_1.collection_2) .SelectMany(c_2 => c_2.collection_3) .Select(c_3 => c_3); var query2 = collection_1 .SelectMany(c_1 => c_1.collection_2 .SelectMany(c_2 => c_2.collection_3.Select(c_3 => c_3))); 

b) I believe that two queries cannot always be used interchangeably? For example, if we want the output elements to also contain the values c_1 and c_2 , then we achieve this only with query2 , but not with query1 :

  var query2 = collection_1 .SelectMany(c_1 => c_1.collection_2 .SelectMany(c_2 => c_2.collection_3.Select(c_3 => new { c_1, c_2, c_3 } ))); 

?

thanks

+4
source share
2 answers

Scanned fragments seem to be invalid. c_3 not defined as part of the Select statement, so if I do not understand something, this will not compile.

It seems you are trying to select collection_3 elements, but this is done implicitly with SelectMany , so the final Select statements in both cases are redundant. Take them out and the two queries are equivalent.

All you need is:

 var query = collection_1 .SelectMany(c_1 => c_1.collection_2) .SelectMany(c_2 => c_2.collection_3); 

Update: x => x is an identical mapping, so Select(x => x) always redundant, regardless of context. It just means "for each item in the sequence, select the item."

The second fragment, of course, is different, and the SelectMany and Select operators really need to be nested to select all three elements: c_1 , c_2 and c_3 .

Like Gert, he says that you should probably use the syntax for understanding the query. This is much more concise and facilitates the mental analysis of the operation of the request.

+1
source

a. The requests are equal because in both cases you get all c_3 in c_1 through c_2 .

b. You cannot get to c_1 and c_2 with these requests, as you suggest. If you want you to need this overload SelectMany . This smooth syntax is pretty awkward. This is typically the case when a comprehensive syntax that does the same thing is much better:

 from c_1 in colection_1 from c_2 in c_1.collection_2 from c_3 in c_2.collection_3 select new { c_1.x, c_2.y, c_3.z } 
+1
source

Source: https://habr.com/ru/post/1441359/


All Articles