Resolved Translating Linq query from SQL to Lambda syntax

larryg

New member
Joined
Mar 27, 2021
Messages
3
Programming Experience
Beginner
Hi,

In reading the 101 Linq Samples, I have come across the following example:

C#:
List<Customer> customers = GetCustomerList();

var orders = from c in customers
             from o in c.Orders
             where o.OrderDate >= new DateTime(1998, 1, 1)
             select (c.CustomerID, o.OrderID, o.OrderDate);

I'm looking to find the code equivalent using the lambda syntax.
It seems the method to use is SelectMany, is that the case?

Thank you,
Larry
 
Yes, it can be written like this with method syntax:
C#:
var orders = customers.SelectMany(c => c.Orders.Where(o => o.OrderDate >= new DateTime(1998, 1, 1)),
                             (c, o) => new { c.CustomerID, o.OrderID, o.OrderDate });
or
C#:
var orders = customers.SelectMany(c => c.Orders,
                             (c, o) => new { c.CustomerID, o.OrderID, o.OrderDate })
                      .Where(a => a.OrderDate >= new DateTime(1998, 1, 1));
 
There's wasn't much explanation, but the code isn't that complicated, it uses the SelectMany overload that takes a collectionSelector and a resultSelector argument.
Imagine a SelectMany(c => c.Orders) that would just return all orders from all customers flattened, the additional resultSelector lets you transform that while keeping source element (the customer) in scope, that's what (c, o) means.
Here's an article that explains more: LINQ SelectMany in Depth - Kill All Defects
 
There's wasn't much explanation, but the code isn't that complicated, it uses the SelectMany overload that takes a collectionSelector and a resultSelector argument.
Imagine a SelectMany(c => c.Orders) that would just return all orders from all customers flattened, the additional resultSelector lets you transform that while keeping source element (the customer) in scope, that's what (c, o) means.
Here's an article that explains more: LINQ SelectMany in Depth - Kill All Defects
Yes indeed!

The difficulty I'm facing is to understand MSDN.

To give you an example:
C#:
SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>)
  • I read it like that:
    SelectMany is a generic method that takes 3 parameters:
    ...the first being of type IEnumerable<TSource> (ie an enumerable sequence that contains elements of type TSource)
    ...the second being a delegate/a method that takes a parameter of type TSource and returns an enumerable sequence that contains elements of type TCollection
    ...the third being a delegate/a method that takes two parameters (one of type TSource, and another one of type TCollection) and returns an object of type TResult


    Am I right?

  • What I don't get is about the first parameter: we don't have this first parameter in our example of customers and orders, right? Indeed, we only have 2 parameters instead of 3 according to MSDN.

Thanks a lot
 
Those methods listed there are extensions methods. The first parameter is a this parameter. In high-level terms, that basically says that the thing to the left of the dot is the first parameter.
 
To expand on what @Skydiver said, you can write a regular method like this:
C#:
public static class ThingExtensions
{
    public static void DoSomething(Thing source, string text, int number)
    {
        // ...
    }   
}
and then do this:
C#:
var aThing = new Thing();

DoSomething(aThing, "Hello World", 100);
or you can write an extension method like this:
C#:
public static class ThingExtensions
{
    public static void DoSomething(this Thing source, string text, int number)
    {
        // ...
    }   
}
and you can still do as before but you can also do this:
C#:
var aThing = new Thing();

aThing.DoSomething("Hello World", 100);
Extension methods allow you to call a method as though it was an instance member of the type of the first parameter. They were introduced as part of LINQ, with methods like Select, Where and First being extension methods with a first parameter of type IEnumerable<T>. Those methods can thus be called on enumerable lists in a very natural way. Because calling instance methods feels more natural and self-documenting, extension methods have found use far beyond LINQ in many developers' code. Note that an extension method must be declared static in a static class and have the first parameter declared this. It is customary to name the class after the type you're extending and group methods that extend a specific type.
 
Back
Top Bottom