Updated on 07 Oct 2025 by Admin

SelectMany Operator in LINQ

How to think
How to think when working with LINQ

SelectMany Operator

We have already discussed in the previous articles that, like a projector machine projects slides or film onto a screen, meaning that a projector transforms one form of thing into another. Similarly, in LINQ, projection means to take all or some properties of an object, either modify them or don't modify them, and project them into a new type, the same type, or an anonymous type.

SelectMany Operator also belongs to the Projection Operators category, which is used to project each element of a sequence to an IEnumerable<T> and flattens the resulting sequences into one sequence. Here, the type (T) literally can be anything, like a collection of strings, a collection of chars, a collection of complex objects, anything like that.

Let us understand this with an example. Consider the following Author class. The Books property in this class is a collection of strings.

public class Author
{
public string Name { get; set; }
public string Gender { get; set; }
public List<string> Books { get; set; }
public static List<Author> GetAllAuthors()
{
List<Author> authorList = new List<Author>
{
new Author
{
Name = "Sachin",
Gender = "Male",
Books = new List<string> { "Book1 ", "Book2" }
},
new Author
{
Name = "Arjun",
Gender = "Male",
Books = new List<string>{ "Book3 ", "Book4" }
},
new Author
{
Name = "Vikash",
Gender = "Male",
Books = new List<string> { "Book4 ", "Book5" }
},
new Author
{
Name = "Nivi",
Gender = "Female",
Books = new List<string> { "Book6 ", "Book7" }
},
};
return authorList;
}
}

Example 1: Fetch all books written by a specific Author.

Here, if we use the Select operator, then we will get a hierarchical result, which means that to print the result, we will have to use two foreach blocks.

public static void Main()
{
  Author author =new Author();
  var BooksByVikash = author.GetAllAuthors().Where(a = > a.Name == "Vikash").Select(x=>x.Books);
foreach (var books in BooksByVikash)
{
foreach(var book in books)
{
Console.WriteLine(book);
}
}
Console.ReadLine();
}

As you can see, there is something weird in here. This is because we are selecting a collection from a collection, which means GetAllAuthors itself returns a collection of Authors. Now, you must be thinking we only want the books written by a particular Author, then why did we not use Single() just to fetch one particular Author? Actually, we can't do so because Select is an extension method on IEnumerable<T> , which means we can use the SELECT operator with a collection of things only and not with a singleton result.

In short, if there is a collection property and we are selecting that property from a collection of objects, then we will end up with an IEnumerable<List<T> which is a collection of collections.

To solve the above problem, we have SelectMany projection operator, which enables us to project each element of a sequence to an IEnumerable<T> and flattens the resulting sequences into one sequence.

The above example can be rewritten with SelectMany operators are shown below:

public static void Main()
{
Author author =new Author();
var BooksByVikash = author.GetAllAuthors().Where(a => a.Name == "Vikash").SelectMany(x=>x.Books);
foreach (var book in BooksByVikash)
{
Console.WriteLine(book);
}
Console.ReadLine();
}

Notice that the results are now flattened, and to print the result, we just used one foreach block instead of two.

Example 2: Rewrite Example1 using SQL like syntax.

When using SQL-like syntax style, we don't use the SelectMany, instead, we will have an additional from clause, which will get its data from the results of the first from clause.

Authors author= new Author();
IEnumerable<string> booksByVikash= from Author in Author. GetAllAuthors ()
from Book in Author.Books
select Book;
foreach (string Book in booksByVikash)
{
Console.WriteLine(Book);
}

Output:

Output
Output

You need to login to post a comment.

Sharpen Your Skills with These Next Guides