Hi,
I have read many sites/threads on select and select many in LINQ but still don't quite understand.
Does select return one element in a collection and select many flatten a collection (eg List>())?
Thanks
Hi,
I have read many sites/threads on select and select many in LINQ but still don't quite understand.
Does select return one element in a collection and select many flatten a collection (eg List>())?
Thanks
Here's a sample. Hope it clarifies everything:
static void MethodRun()
{
List<Topping> testToppings = new List<Topping> { Topping.Cheese, Topping.Pepperoni, Topping.Sausage };
var firstLetterofToppings = testToppings.Select(top => top.ToString().First());
// returns "C, P, S"
var singleToppingPizzas = testToppings.Select(top => new Pizza(top)).ToArray();
// returns "Pizza(Cheese), Pizza(Pepperoni), Pizza(Sausage)"
List<Topping> firstPizza = new List<Topping> { Topping.Cheese, Topping.Anchovies };
List<Topping> secondPizza = new List<Topping> { Topping.Sausage, Topping.CanadianBacon, Topping.Pepperoni };
List<Topping> thirdPizza = new List<Topping> { Topping.Ham, Topping.Pepperoni };
List<IEnumerable<Topping>> toppingsPurchaseOrder = new List<IEnumerable<Topping>> { firstPizza, secondPizza, thirdPizza };
var toppingsToOrder = toppingsPurchaseOrder.SelectMany(order => order);
//returns "Cheese, Anchovies, Sausage, CanadianBacon, Pepperoni, Ham, Pepperoni"
}
class Pizza
{
public List<Topping> Toppings { get; private set; }
public Pizza(Topping topping) : this(new List<Topping> { topping }) { }
public Pizza(IEnumerable<Topping> toppings)
{
this.Toppings = new List<Topping>();
this.Toppings.AddRange(toppings);
}
}
enum Topping
{
Cheese,
Pepperoni,
Anchovies,
Sausage,
Ham,
CanadianBacon
}
The key is that Select() can select any type of object. It's true that you can select a property of whatever generic value is assigned to your collection, but you can select any other type of object also. SelectMany() just flattens your list.
SelectMany returns a number of objects for each of the object passed into the expression. Select istead returns a single object for each object passed into the expression.
To quote the documentation:
Select Many
Projects each element of a sequence to an IEnumerable<(Of <(T>)>) and flattens the resulting sequences into one sequence.
Select
Projects each element of a sequence into a new form.
You can use SelectMany
if you want to flatten a hierarchy. E.g. if you have Orders
and OrderDetails
. If you want make a selection based upon the orders, but you want as a return the OrderDetails
use SelectMany
.
var result = db.Orders
.Where(x => x.CustomerId == 500) // input to next expression is IEnumerable<Order>
.SelectMany(x => x.OrderDetails) // input to next expression is IEnumerable<OrderDetails>
.Sum(x => x.PositionTotal);
var result = db.Orders
.Where(x => x.CustomerId == 500) // input to next expression is IEnumerable<Order>
.Select(x => CustomerName);