Falling in Love with LINQ - Part 6: Expression Parameters

by Larry Spencer Friday, December 2, 2011 3:12 AM

Throughout this series on LINQ, we have used Lambda expressions in our LINQ statements. For example, in Part 3 we saw this code, which includes a Lambda in the call to OrderByDescending:

 

static IEnumerable<City> GetLargest(LinqDemoEntities context, int numDesired)
{
    #region Generated SQL
    //    SELECT TOP (15) 
    //    [Extent1].[Name] AS [Name], 
    //    [Extent1].[StateCode] AS [StateCode], 
    //    [Extent1].[Population] AS [Population]
    //    FROM [dbo].[Cities] AS [Extent1]
    //    ORDER BY [Extent1].[Population] DESC
    #endregion

    return context.Cities
         .OrderByDescending(c => c.Population)
         .Take(numDesired);
}

 

If you were to download the code (LinqDemo.zip), find the OrderByDescending call in Program.cs in the Demo6 project, right-click on it and then select Go To Definition from the pop-up menu, you would see its signature:

 

public static IOrderedQueryable<TSource> OrderByDescending<TSource, TKey>(
    this IQueryable<TSource> source, 
    Expression<Func<TSource, TKey>> keySelector);

 

The first parameter simply says that OrderByDescending is an extension method on IQueryable<>. It's the second parameter that interests us. Let's unpack what Expression<Func<TSource,TKey>> means.

First of all, it's an Expression, defined in the System.Linq.Expressions namespace. The most important thing to remember about Expressions is that they are simply data. Even our expression, which looks like a Lambda that actually does something, is just data. It's the job of the IQueryable<> implementation to parse the data and come up with something useful. In our case, it's LINQ to Entities that does that task, and it creates the SQL that you see in the comments above. You can see that our call to OrderByDescending, with its Expression parameter, precipitated the ORDER BY clause in the SQL.

So what's up with the Lambda? Well, it turns out that the C# compiler is able to turn a Lambda into an Expression for you. (We'll see in the next post that it is rather tedious to build an Expression yourself.) Actually, the compiler can't turn just any Lambda into an Expression; it must be an Expression Lambda. That's a Lambda whose component after the => is just a C# expression, not a statement block.

To recap, what's really going on in that OrderByDescending call is

  1. We used a Lambda...
  2. ...to create an Expression...
  3. ...that LINQ to Entities parsed...
  4. ...and used to emit SQL.

All that from one parameter!

In the next post of this series, I'll discuss the difference between an Expression and a Func as it relates to LINQ.

Tags: ,

All | Entity Framework | Talks

Pingbacks and trackbacks (1)+

Add comment

About the Author

Larry Spencer

Larry Spencer develops software with the Microsoft .NET Framework for ScerIS, a document-management company in Sudbury, MA.