C#
Beginner
1 min read
LINQ Join and Advanced Queries
Example
// Join, GroupJoin, SelectMany, and deferred execution
record Customer(int Id, string Name, string Country);
record Order(int Id, int CustomerId, decimal Amount);
var customers = new List<Customer>
{
new(1, "Alice", "UK"),
new(2, "Bob", "US"),
new(3, "Carol", "UK"),
new(4, "Dave", "CA"), // no orders
};
var orders = new List<Order>
{
new(101, 1, 250m),
new(102, 1, 400m),
new(103, 2, 150m),
new(104, 3, 600m),
new(105, 3, 200m),
};
// Inner join
var joined = customers.Join(
orders,
c => c.Id,
o => o.CustomerId,
(c, o) => new { c.Name, o.Amount });
foreach (var item in joined)
Console.WriteLine($"{item.Name}: {item.Amount:C}");
// GroupJoin (left outer join) — includes Dave with empty orders
var withOrders = customers.GroupJoin(
orders,
c => c.Id,
o => o.CustomerId,
(c, os) => new { c.Name, Total = os.Sum(o => o.Amount), Count = os.Count() });
foreach (var row in withOrders)
Console.WriteLine($"{row.Name,-8} {row.Count} orders, total {row.Total:C}");
// SelectMany — flatten per-customer orders
var allLines = customers.SelectMany(
c => orders.Where(o => o.CustomerId == c.Id),
(c, o) => $"{c.Name} - Order#{o.Id} - {o.Amount:C}");
foreach (var line in allLines) Console.WriteLine(line);
// Deferred execution demo
var source = new List<int> { 1, 2, 3 };
var query = source.Where(n => n > 1); // not yet evaluated
source.Add(4); // modify source
Console.WriteLine(string.Join(",", query)); // 2,3,4 — sees the new element