.NET 11 Preview - Simplification Of LINQ Joins Without Result Selectors
[C#, .NET, LINQ]
A staple of .NET programming is the use of LINQ to simplify a lot of common operations.
LINQ also offers the ability to join data, and perform a variety of operations.
Take, for example, the following type for a Product:
public class Product
{
public required int ID { get; init; }
public required string Name { get; init; }
}
Let us add another type, an Order:
public class Order
{
public required int OrderID { get; init; }
public required int ProductID { get; init; }
public required int Quantity { get; init; }
}
We then create a collection of Product:
Product[] products = [
new Product { ID = 1, Name = "Mango" },
new Product { ID = 2, Name = "Banana" },
new Product { ID = 3, Name = "Potato" },
new Product { ID = 4, Name = "Cabbage" },
];
And another collection of Order:
Order[] orders =
[
new Order{ OrderID=1, ProductID=1,Quantity=10 },
new Order{ OrderID=1, ProductID=2,Quantity=13 },
new Order{ OrderID=2, ProductID=3,Quantity=5 },
new Order{ OrderID=2, ProductID=4,Quantity=8 },
];
Suppose we wanted to iterate over all the orders and print the Product name and quantity. We can achieve this using a LINQ JOIN, like this:
var result = products.Join(orders,
product => product.ProductID,
order => order.ProductID,
(product, order) => (product, order));
This would project the result of each join operation into a tuple that we can iterate over, like this:
foreach (var (product, order) in result)
{
Console.WriteLine($"Product: {product.Name}, Quantity: {order.Quantity}");
}
This will print the following:
Product: Mango, Quantity: 10
Product: Banana, Quantity: 13
Product: Potato, Quantity: 5
Product: Cabbage, Quantity: 8

Note that there is some ceremony, including generation of an intermediate resultset of tuples:
var result = products.Join(orders,
product => product.ProductID,
order => order.ProductID,
(product, order) => (product, order));
This has been simplified in .NET 11.
We can get the exact same result like this:
var newResult = products.Join(orders,
product => product.ProductID,
order => order.ProductID);
Note here we do not need to construct our tuple in advance, and that the generated data structure being returned is identical in both cases:

TLDR
Projection of LINQ JOIN results is simplified in .NET 11
The code is in my GitHub.
Happy hacking!