LINQ – Lambda Expression vs Query Expression

Yan Cui

I help clients go faster for less using serverless technologies.

As you’re probably aware of already, LINQ comes in two flavours – using Lambda expressions and using SQL-like query expressions:

Func<int, bool> isEven = i => i % 2 == 0;
int[] ints = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

// using Query expression
var evensQuery = from i in ints where isEven(i) select i;
// using Lambda expression
var evensLambda = ints.Where(isEven);

Both yields the same result because query expressions are translated into their lambda expressions before they’re compiled. So performance-wise, there’s no difference whatsoever between the two.

Which one you should use is mostly personal preference, many people prefer lambda expressions because they’re shorter and more concise, but personally I prefer the query syntax having worked extensively with SQL. With that said, it’s important to bear in mind that there are situations where one will be better suited than the other.

Joins

Here’s an example of how you can join sequence together using Lambda and query expressions:

class Person
{
    public string Name { get; set; }
}
class Pet
{
    public string Name { get; set; }
    public Person Owner { get; set; }
}

void Main()
{
    var magnus = new Person { Name = "Hedlund, Magnus" };
    var terry = new Person { Name = "Adams, Terry" };
    var charlotte = new Person { Name = "Weiss, Charlotte" };
    var barley = new Pet { Name = "Barley", Owner = terry };
    var boots = new Pet { Name = "Boots", Owner = terry };
    var whiskers = new Pet { Name = "Whiskers", Owner = charlotte };
    var daisy = new Pet { Name = "Daisy", Owner = magnus };
    var people = new List<Person> { magnus, terry, charlotte };
    var pets = new List<Pet> { barley, boots, whiskers, daisy };

    // using lambda expression
    var lambda = people.Join(pets,              // outer sequence
                             person => person,  // inner sequence key
                             pet => pet.Owner,  // outer sequence key
                             (person, pet) =>
                                 new { OwnerName = person.Name, Pet = pet.Name });

    // using query expression
    var query = from person in people
                join pet in pets on person equals pet.Owner
                select new { OwnerName = person.Name, Pet = pet.Name };
}

Again, both yields the same result and there is no performance penalties associated with either, but it’s easy to see why query syntax is far more readable and expressive of your intent here than the lambda expression!

Lambda-Only Functions

There are a number of methods that are only available with the Lambda expression, Single(), Take(), Skip(), First() just to name a few. Although you can mix and match the two by calling the Lambda-only methods at the end of the query:

// mix and match query and Lambda syntax
var query = (from person in people
             join pet in pets on person equals pet.Owner
             select new { OwnerName = person.Name, Pet = pet.Name }).Skip(1).Take(2);

As this reduces the readability of your code, it’s generally better to first assign the result of a query expression to a variable and then use Lambda expression using that variable:

var query = from person in people
            join pet in pets on person equals pet.Owner
            select new { OwnerName = person.Name, Pet = pet.Name };

var result = query.Skip(1).Take(2);

Both versions returns the same result because of delayed execution (the query is not executed against the underlying list until you try to iterate through the result variable). Also, because query expressions are translated to Lambda expressions first before being compiled there will not be performance penalties either. BUT, if you don’t want delayed execution, or need to use one of the aggregate functions such as Average() or Sum(), for example, you should be aware of the possibility of the underlying sequence being modified between the assignments to query and result. In this case,I’d argue it’s best to use Lambda expressions to start with or add the Lambda-only methods to the query expression.


 

Whenever you’re ready, here are 4 ways I can help you:

  1. If you want a one-stop shop to help you quickly level up your serverless skills, you should check out my Production-Ready Serverless workshop. Over 20 AWS Heroes & Community Builders have passed through this workshop, plus 1000+ students from the likes of AWS, LEGO, Booking, HBO and Siemens.
  2. If you want to learn how to test serverless applications without all the pain and hassle, you should check out my latest course, Testing Serverless Architectures.
  3. If you’re a manager or founder and want to help your team move faster and build better software, then check out my consulting services.
  4. If you just want to hang out, talk serverless, or ask for help, then you should join my FREE Community.

 


7 thoughts on “LINQ – Lambda Expression vs Query Expression”

  1. How to convert this linq query into lambda expression.
    I’m using ASP.NET MVC (Visual Basic) – Visual Studio 2010.

    Dim query = From c In Me.ObjectContext.Customer
    Join uc In Me.ObjectContext.UserCostumer On c.CompanyID Equals uc.CompanyID And c.CustomerID Equals uc.CustomerID
    Where c.CompanyID = “AC” And uc.User = “admin”
    Select c

    HELP ME PLEASEEEEEEEEEE! :(

  2. theburningmonk

    Hi ReyPorto,

    Here’s how you might write this query in lambda:

    var customers = new List {
    new Customer { CompanyId = “AC”, CustomerId = “Customer1” },
    new Customer { CompanyId = “not-AC”, CustomerId = “Customer2” },
    };

    var userCustomers = new List {
    new UserCustomer { CompanyId = “AC”, CustomerId = “Customer1”, User = “not-admin” },
    new UserCustomer { CompanyId = “AC”, CustomerId = “Customer1”, User = “admin” },
    new UserCustomer { CompanyId = “AC”, CustomerId = “Customer2”, User = “not-admin” },
    new UserCustomer { CompanyId = “AC”, CustomerId = “Customer2”, User = “admin” },
    new UserCustomer { CompanyId = “not-AC”, CustomerId = “Customer1”, User = “not-admin” },
    new UserCustomer { CompanyId = “not-AC”, CustomerId = “Customer1”, User = “admin” },
    new UserCustomer { CompanyId = “not-AC”, CustomerId = “Customer2”, User = “not-admin” },
    new UserCustomer { CompanyId = “not-AC”, CustomerId = “Customer2”, User = “admin” }
    };

    // using query expression
    var query =
    from c in customers
    join uc in userCustomers on
    new { c.CompanyId, c.CustomerId } equals new { uc.CompanyId, uc.CustomerId }
    where c.CompanyId == “AC” && uc.User == “admin”
    select c;

    // using lambda expressions
    var lambda =
    customers
    .Where(c => c.CompanyId == “AC”) // inner sequence
    .Join(
    userCustomers.Where(uc => uc.User == “admin”), // outer sequence
    c => new { c.CompanyId, c.CustomerId }, // inner key selector
    uc => new { uc.CompanyId, uc.CustomerId }, // outer key selector
    (c, uc) => c);

    Both approach yields the same result (customer with company Id “AC” and customer Id “Customer1”), but as you can see, lambda expression is much harder to write and read!

    Hope this helps!

  3. OMG :O Thank u very much!!!!!! The result is the same…
    THANKSSSS!!!!! Blessings!!!! =)
    =)
    =)

  4. thank you. i was just coding lambda expressions and linq and didn’t have a clear idea about the difference other than the syntax.

  5. Pingback: Even more powerful LINQ debugging, now with Query Syntax support! – The OzCode Blog

Leave a Comment

Your email address will not be published. Required fields are marked *