C# LINQ SelectMany — Complete Guide
In this tutorial, you'll learn about C# LINQ SelectMany. We cover key concepts, practical examples, and best practices.
You have a list of orders, each containing multiple items. You need a flat list of all items across all orders. You write nested foreach loops. The LINQ SelectMany method projects each element to a sequence and flattens the result into a single sequence.
Wrong
var allItems = new List<OrderItem>();
foreach (var order in orders)
{
foreach (var item in order.Items)
{
allItems.Add(item);
}
}
Output: Works. Six lines of nested loops for a simple flatten operation.
Right
var allItems = orders.SelectMany(order => order.Items).ToList();
Output: Same list, one line. SelectMany takes each order, extracts order.Items, and flattens all item lists into one.
SelectMany also provides the parent index:
var indexed = orders.SelectMany((order, orderIndex) =>
order.Items.Select(item => $"{orderIndex}: {item.Name}"));
For query syntax:
var allItems = from order in orders
from item in order.Items
select item;
Prevention
- Use
SelectManyfor nestedforeachflattening. - Use
SelectManywhen each input element produces zero or more output elements. - Use
SelectManywithIQueryablefor server-side flattening (cross-join orSelectManyin SQL). - Use
SelectManywith an optional result selector:.SelectMany(x => x.Items, (x, item) => new { x.Id, item.Name }). - Use
Selectwhen each input produces exactly one output element. - Use
Wherefollowed bySelectif you need filtering before flattening.
Common Mistakes with linq select many
- Using
headandtailinstead of pattern matching, causing runtime errors on empty lists - Forgetting that lazy evaluation defers computation until the value is forced, causing space leaks with unevaluated thunks
- Using
returnto exit a function early instead of wrapping a pure value in the monad
These mistakes appear frequently in real-world CSHARP code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
SelectMany is used in DodaTech's reporting to flatten hierarchical data. For more LINQ, visit DodaTech.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro