I'd like to know how to use SelectMany()
. It seems to take so many arguments and from my own research I noticed that SelectMany()
might be the 'father' of all other select operations.
Select and SelectMany are projection operators. A select operator is used to select value from a collection and SelectMany operator is used to selecting values from a collection of collection i.e. nested collection.
@flem They can never be null because that's how Where and SelectMany work. If the input is null they throw an exception, and if it's not null the result will either be a sequence of items, or an empty sequence.
SingleOrDefault() – Same as Single(), but it can handle the null value. First() - There is at least one result, an exception is thrown if no result is returned. FirstOrDefault() - Same as First(), but not thrown any exception or return null when there is no result.
The major difference between IQueryable and IEnumerable is that IQueryable executes query with filters whereas IEnumerable executes the query first and then it filters the data based on conditions.
Select many allows you to select a property from your query source that is an IEnumerable<T> collection, but instead of returning a collection of collections (IEnumerable<IEnumerable<T>>) it will flatten the collections into a single collection.
Here's an example that you can run to demonstrate the differences between Select and SelectMany:
//set up some data for our example
var tuple1 = new { Name = "Tuple1", Values = new int [] { 1, 2, 3 } };
var tuple2 = new { Name = "Tuple2", Values = new int [] { 4, 5, 6 } };
var tuple3 = new { Name = "Tuple3", Values = new int [] { 7, 8, 9 } };
//put the tuples into a collection
var tuples = new [] { tuple1, tuple2, tuple3 };
//"tupleValues" is an IEnumerable<IEnumerable<int>> that contains { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }
var tupleValues = tuples.Select(t => t.Values);
//"tupleSelectManyValues" is an IEnumerable<int> that contains { 1, 2, 3, 4, 5, 6, 7, 8, 9 }
var tupleSelectManyValues = tuples.SelectMany(t => t.Values);
By using SelectMany you make it easier to query values within child collections.
There are several overloads to SelectMany
. One of them allows you to keep track of any relationship between parent and children while traversing the hierarchy.
Example: suppose you have the following structure: League -> Teams -> Player
You can easily return a flat collection of players. However you may loose any reference to the team a player is part of.
Fortunately there is an overload for such purpose:
var teamsAndTheirLeagues =
from helper in leagues.SelectMany
( l => l.Teams
, ( league, team ) => new { league, team } )
where helper.team.Players.Count > 2
&& helper.league.Teams.Count < 10
select new
{ LeagueID = helper.league.ID
, Team = helper.team
};
The previous example is taken from Dan's IK blog:
http://blogs.interknowlogy.com/2008/10/10/use-linqs-selectmany-method-to-flatten-collections/
I strongly recommend you take a look at it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With