Author avatar

Dániel Szabó

Query and Method Syntax Translation in C#

Dániel Szabó

  • Feb 24, 2020
  • 5 Min read
  • 799 Views
  • Feb 24, 2020
  • 5 Min read
  • 799 Views
Languages Frameworks and Tools
C#

Introduction

LINQ is short for Language-Integrated Query, which is basically a set of technologies. The idea from Microsoft was to integrate query capabilities directly into the C# language. For these types of queries, you need to know different query languages to work with SQL databases, XML, or various web services, unlike with traditional queries which are expressed as simple strings and interpreted by the engine.

In this guide, we will first clarify what LINQ is with an example, then we'll demonstrate the difference between query and method syntax.

LINQ

Let's create a small demonstration that uses LINQ to filter lottery numbers higher than a specified value.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using System;
using System.Linq;
using System.Collections.Generic;

namespace Pluralsight
{
    public class Linqing
    {
        
        public static void Main()
        {
            int[] lottery = new int[] { 11,22,33,44,55,66};

            IEnumerable<int> lotteryQuery =
                from lot in lottery
                where lot > 20
                select lot;

            foreach (int i in lotteryQuery)
            {
                Console.Write(i + " ");
            }
            Console.ReadKey();
        }
    }
}
csharp

The output is as follows.

1
22 33 44 55 66
bash

At the heart here lies the LINQ query, which is very similar to the SQL queries most of us love to write. The where clause defines the filter above that we are interested in. Then foreach allows us to grab the values caught in the filter.

1
2
3
from lot in lottery
where lot > 20
select lot;
csharp

Query and method syntax are semantically identical, but most developers, including me, find the query syntax easier to read and troubleshoot. The reference documentation for the query operators can be found here. We could say that these two approaches are just different tools for the same job. Behind the scenes, the compiler always converts the query syntax to method syntax as it needs function calls.

We can convert our query syntax to method syntax this way.

1
IEnumerable<int> lotteryQuery = lottery.Where(num => num > 20);
csharp

Iterating over the results in the for loop produces the same results. If we were to check the type of the output variable, it would be revealed that it is an instance of the IEnumerable<T> class.

The general rule of thumb for either method or query syntax is:

  1. Specify where to select from
  2. Filter if necessary
  3. Order if necessary
  4. Capture the results

With method syntax we have functions such as:

  1. Select()
  2. Where()
  3. OrdertBy()
  4. etc.

The Let Keyword

The let keyword is a pretty amazing feature of query-based syntax. Simply, it lets you store the results for later use in the query. Let's look at a demonstration. Imagine that we have a server park that includes the server's name, type, and uptime. We want to query the servers with more than 2 years of uptime.

In query syntax, it would look like this.

1
2
3
4
5
6
var MS =
    from server in servers
    let age = GetUptime(server)
    where age > 2
    orderby age
    select server.Name;
csharp

In method syntax, we could do something like this.

1
2
3
4
5
6
var QS = servers
    .Select(server => new { 
      age = GetYearsWorking(server), Name = server.Name })
    .Where(x => x.age > 4)
    .OrderBy(x => x.age)
    .Select(x => x.Name);
csharp

In this case, the method syntax makes it harder to unwrap what the intention was, and in case of troubleshooting it would not be ideal.

Multiple Sources

There might be a situation where you have two different datasources and you would like to project each element of a sequence to an IEnumerable<T>.

1
2
3
4
5
6
7
8
9
var ids = Enumerable.Range(1, 10); //1,2,3
var names = new string[] { "DC", "DNS", "DHCP", "APP", "ISM", "FND", "SQL", ""};
 
var QS = from id in ids
               from name in names
               select $"map [{id}, {name}]";
 
var MS = 
    rows.SelectMany(id => names, (i, n) => $"cell [{i}, {n}]");
csharp

Iterating over the datastructure, the following output would be shown.

1
2
3
4
5
6
7
8
9
10
cell [1, DC]
cell [1, DNS]
cell [1, DHCP]
cell [1, APP]
cell [1, ISM]
cell [1, FND]
cell [1, SQL]
cell [1, ]
cell [2, DC]
...
bash

The query syntax is easy to follow, while the method syntax introduces head-scratching into the equation.

There is a fun github repository that has a tool for converting between these two syntaxes, which you can check out here.

Conclusion

In this guide, we have seen what query and method syntax approaches are in LINQ. We also learned that no matter which we use, the query syntax is converted to method syntax behind the scenes. I hope this guide has been informative to you and I would like to thank you for reading it!

11