
Using LINQ For Each to Iterate Collections
Author - Abdul Rahman (Bhai)
LINQ
26 Articles
Table of Contents
What we gonna do?
In this article, let's learn about how to use ForEach in LINQ in .NET.
Note: If you have not done so already, I recommend you read the article on Using LINQ Count Min Max Average and Sum to Aggregate data.
When working with collection, we can perform set operation in them using LINQ ForEach() method. A set operation that iterates over an entire collection and allows us to set a property value within that collection. This is similar to a SQL UPDATE command.
Why we gonna do?
LINQ ForEach() is used to answer questions about collection such as
- Calculate a line total or set the total sales for a product.
- Printing each element to the console.
- Updating a property of each object in the collection.
How we gonna do?
Using LINQ For Each to iterate collections
Set operation can be done using ForEach with quert syntaz or method syntax. In a real-world scenario, you may want to calculate Total Stock Value of items in inventory. We can use query syntax to assign values to a property within an object. This can be done using a temporary variable, like let tmp, and then assigning the property value you want to update. For instance, let tmp = product.TotalStockValue = product.Price * product.Quantity sets the length of a product name.
Using the method syntax, you can use the ForEach method to directly set the property value of an object in a collection. For example, product.TotalStockValue = product.Price * product.Quantity assigns the length of the product name to another property within the product object.
IEnumerable<Product> products = GetProducts();
//Method Syntax
products.ForEach(product => product.TotalStock = product.Price * product.Quantity);
//Query Syntax
(from product in products
let tmp = product.TotalStock = product.Price * product.Quantity
select product);
Using Sub Query in For Each
we'll learn how to use a sub query to calculate the total sales for each product in our Product object. Our Product class has some typical properties like Name, Color, and Price, but we also have a couple of calculated properties, including TotalStock and TotalSales. TotalSales is marked as a nullable data type so that we can have either null or the total sales in there.
List<Product> products = GetProducts();
List<Sale> sales = GetSales();
//Method Syntax
products.ForEach(product => product.TotalSale
= sales.Where(sale => sale.ProductId == product.Id).Sum(sale => product.Price * sale.Quantity));
//Query Syntax
(from product in products
let tmp = product.TotalSale
= sales.Where(sale => sale.ProductId == product.Id).Sum(sale => product.Price * sale.Quantity)
select product);
Using Custom Method in For Each
We can use alternative method of calculating the TotalSales property in the Product object. Rather than using a subquery, we can use a method that allows us to call a method inside the query. We then call the CalculateTotalSalesForProduct method, passing in the current product and the sales collection. This method returns a decimal value calculated by running the same sales.Where query as before. By breaking out the calculation into a separate method, we can use more complex logic if needed. The resulting collection is an IEnumerable of Products, which we can filter using the Where method to only include those products with a TotalSales greater than 0. Finally, we convert the resulting collection to a list and return it.
List<Product> products = GetProducts();
List<Sale> sales = GetSales();
//Method Syntax
products.ForEach(product => product.TotalSale = CalculateTotalSalesForProduct(sales, product));
products = products.Where(product => product.TotalSale > 0).ToList();
//Query Syntax
(from product in products
let tmp = product.TotalSale = CalculateTotalSalesForProduct(sales, product)
select product);
products = products.Where(product => product.TotalSale > 0).ToList();
decimal CalculateTotalSalesForProduct(IEnumerable<Sale> sales, Product product)
{
return sales.Where(sale => sale.ProductId == product.Id).Sum(sale => product.Price * sale.Quantity);
}
Summary
In this article we learn't how to iterate collections using ForEach. This allows you to set / update values for objects inside collection. We also learnt how to use sub queries inside ForEach for performing set operations. By using sub queries, we can easily calculate aggregate values for a collection based on related data in another collection. Overall by using query syntax or the method syntax, you can assign values to properties within objects in a collection and make updates efficiently.