LINQ is awesome, right? It’s one of those things everyone loves from first sight. Like smartphones in the early days – you just know it’s right.

For this post, I’ll assume you already know LINQ, use it and love it.

LINQ comes in two flavors – the Query Syntax and Method Syntax (aka Fluent Syntax). For example, the following is the same:

var numbers = Enumerable.Range(1, 100); //1,2,...,100
//query syntax:
var query = from n in numbers
    where n % 3 == 0
    select n * 2;
//method syntax:
var method = numbers
    .Where(n => n % 3 == 0)
    .Select(n => n * 2);

For some reason, most developers (including myself) feel much more comfortable with Method Syntax. I can’t explain it fully, but I think the reason is that programmers are used to regular method calls. Unlike query-syntax, which is sort of a new language (well, kind of like SQL but still much less familiar than C#).

There isn’t any distinct advantage of one over the other. In fact, any query syntax can be transformed into method syntax (See Dudi Keleti’s automatic Roslyn converter ).

However, method-syntax isn’t always a better syntax. There are several cases where query syntax is better, and this is what this post is all about. By better, I mean it makes more readable code. You’ll see some cool examples where method-syntax creates pretty complicated code that can be replaced by a short and neat query-syntax expression.

The awesome ‘let’ keyword

One of the nicest things about the query-syntax is the let keyword. It allows to store a result for later use in the query. Here’s an example:

var querySyntax =
    from person in people
    let yearsWorking = GetYearsWorking(person)
    where yearsWorking > 4
    orderby yearsWorking
    select person.Name;

var methodSyntax = people
    .Select(person => new { 
      YearsWorking = GetYearsWorking(person), Name = person.Name })
    .Where(x => x.YearsWorking > 4)
    .OrderBy(x => x.YearsWorking)
    .Select(x => x.Name);

As you can see, with query syntax everything is nice and clean. Method-syntax isn’t terrible, but it requires you to create anonymous classes and use those for the rest of the query.

So whenever you want to “save” a value in addition to the queried collection, consider using the let clause.

Multiple data sources

If you have several data sources for the query, the query-syntax is probably a better choice. The reason is that you can use the from keyword several times. For example:

var rows = Enumerable.Range(1, 3); //1,2,3
var columns = new string[] { "A", "B", "C"};

var querySyntax = from row in rows
               from col in columns
               select $"cell [{row}, {col}]";

var methodSyntax = 
    rows.SelectMany(row => columns, (r, c) => $"cell [{r}, {c}]");

foreach (var cell in methodSyntax)
{
    Console.WriteLine(cell);
}
//output:
//cell[1, A]
//cell[1, B]
//cell[1, C]
//cell[2, A]
//cell[2, B]
//cell[2, C]
//cell[3, A]
//cell[3, B]
//cell[3, C]

The purpose here is to get a collection with all the possible combinations from 2 sources. With query-syntax, the code is simple and self-explanatory. The method-syntax, on the other hand, requires a head-scratching to understand.

To understand how both ways work to give the same result, you can use the OzCode VS extension’s LINQ feature :

OrderBy with multiple orderings

In both query-syntax and method-syntax, you can easily perform multiple orderings. For example, we can order people by Age and then Income, where Age is the first ordering and Income the second one. This means that people with the same Age will be ordered by Income.

var people = new Person[]
{
    new Person() {Age = 20, Income = 5000, Name = "Peter"},
    new Person() {Age = 30, Income = 8000, Name = "Alfredo"},
    new Person() {Age = 30, Income = 7000, Name = "Bo"},
    new Person() {Age = 20, Income = 4000, Name = "Jo"},
    new Person() {Age = 20, Income = 6000, Name = "Amanda"},
    new Person() {Age = 30, Income = 5500, Name = "Maxim"},
};

var querySyntax = from person in people
    orderby person.Age, person.Income
    select $"{person.Age} {person.Income} {person.Name}";
var methodSyntax = people
    .OrderBy(person => person.Age)
    .ThenBy(person => person.Income)
    .Select(person => $"{person.Age} {person.Income} {person.Name}");

//result
//20 4000 Jo
//20 5000 Peter
//20 6000 Amanda
//30 5500 Maxim
//30 7000 Bo
//30 8000 Alfredo

I admit, both syntaxes are good and the difference is not as big as in the other cases. But query-syntax is still nicer.

GroupBy vs group

The GroupBy extension method of method-syntax is pretty similar to group in query-syntax. For example:

var names = new string[] { "Alex", "George", "Alfredo", "Bo", "Greg", "Maxim" };

var querySyntax = from name in names
    group name by name[0];

var methodSyntax = names
    .GroupBy(name => name[0], name => name);

foreach (var pair in querySyntax)
{
    var names1 = string.Join(", ", pair.ToList());
    Console.WriteLine($"Key = {pair.Key} Names = {names1}");
}
//output:
//Key = A Names = Alex, Alfredo
//Key = G Names = George, Greg
//Key = B Names = Bo
//Key = M Names = Maxim

The method-syntax is a bit unclear. What does the second parameter stand for? Sure, once you think about it a bit, it becomes clearer. But I don’t want to think when I’m looking at code, I want to read it like a book. A children’s book if possible.

Joins are fun with query-syntax

Well, maybe joins are never truly fun, but they are much nicer with query-syntax. Here is inner join for example:

var categories = new Category[]
{
    new Category() {Name = "Toys", ID = 1},
    new Category() {Name = "Electrical", ID = 2},
};
var products = new Product[]
{
    new Product(){Name = "Toy car", CategoryID =1 },
    new Product(){Name = "Blender", CategoryID =2 },
    new Product(){Name = "Washing machine", CategoryID =2 },
    new Product(){Name = "Bear", CategoryID =1 },
};

var querySyntax =
    from category in categories
    join prod in products on category.ID equals prod.CategoryID
    select new { ProductName = prod.Name, Category = category.Name };

var methodSyntax = categories.Join(products,
    category => category.ID,
    prod => prod.CategoryID,
    (category, prod) => new {ProductName = prod.Name, Category = category.Name});

// result:
// ProductName: Toy car, Category: Toys
// ProductName: Bear, Category: Toys
// Blender - Electrical
// Washing machine - Electrical

In the method-syntax way, the 2nd and 3rd parameters of Join are compared. But unlike in query-syntax, it’s not really clear from the code. In query-syntax it’s much clearer with
join prod in products on category.ID equals prod.CategoryID

As a rule of thumb, whenever you need to Join collections, the query-syntax is going to be better. And by better I mean more readable and easier code.

Summary

In most cases, with simple operators like Where, Select and OrderBy the method-syntax is great. It provides an easy-to-understand functional syntax. You can switch to query-syntax for those, but I don’t recommend it. Even if you get used to it, remember that most programmers still find method-syntax more readable.

In some special cases, like the ones described above, query-syntax can be better. Those cases are:

  • Multiple data sources
  • “Saving” values for later in the query (‘let’ keyword)
  • Order-By with multiple orders
  • Group-By’s
  • Joins

As I said in the beginning, there’s no distinct advantage of one syntax over the other besides readability. There’s even a cheat sheet if you want to convert between them.

M ↓   Markdown
?
Anonymous
0 points
6 years ago

> var methodSyntax = names
> .GroupBy(name => name[0], name => name);

Personally I prefer writing this way:

var methodSyntax = names
.GroupBy(name => name[0]);

The result is the same but more readable and closer to the query form.

?
Anonymous
0 points
6 years ago

Thanks SS, good example

M
Mithrandir
0 points
10 months ago

Unfortunately, a cheat sheet is not accessible anymore =_(

?
Anonymous
0 points
6 years ago

Hey, nice article!

The link to the cheatsheet(http://www.bartdesmet.net/b...) Is not resolving for me. Do you have an alternative URL?

?
Anonymous
0 points
6 years ago

Thanks, it probably went down very recently. I didn't find any alternative, but I'll try to contact Bart and ask for permission to upload his cheat sheet.

?
Anonymous
0 points
6 years ago

Thanks.
Could add nice sample with many joins Inner and left to see the huge difference in syntaxes.

?
Anonymous
0 points
6 years ago

I actually tried to add such a sample but couldn't make it for some reason. Don't remember exactly but I think it was too complicated.

?
Anonymous
0 points
6 years ago

What about the difference in performance between both approaches?

?
Anonymous
0 points
6 years ago

Technically "Query Form" does not exist as a language and it is only a syntactic sugar. Compiler translates Query form into the same Method Call Chain form. That said there may be some cases where compiler might not translate Query form into a method syntax in an optimal form causing some unnecessary intermediate steps or choosing a more expensive solution to achieve the same result.

I do not have a specific example of that though because I've encountered that many years ago, but it is one of the reasons why I stick to method chain syntax. Another reason is because query form can only do maybe half the stuff method syntax can and it feels very ugly trying to mix them.

?
Anonymous
0 points
6 years ago

I have a more practical distinction, based on what kind of code you are writing. Not surprisingly, query syntax works a lot better for making queries to providers using SQL, the biggest advantage being join and let that you mentioned.

?
Anonymous
0 points
6 years ago

My question was the title of your article. My answer came from the content of said title. Nicely done. :)

?
Anonymous
0 points
6 years ago

Thanks Larry!

?
Anonymous
0 points
21 months ago

Thank you

?
Anonymous
0 points
6 years ago

Awesome advise, good concrete examples when query syntax really adds value (I'm in the camp of query syntax anyhow, but this makes it really concrete!).