1. Introduction
In the LINQ world, there are two main "schools" of writing queries, two styles that at first glance might look totally different. These are Query Syntax and Method Syntax. And if you ever thought programming is all about logic, today we're adding a bit of art, because picking a syntax is often like choosing between a brush and a pencil: both draw, but one might be better for color, the other for outlines.
Why do we need two syntaxes? Good question! Imagine you want to order coffee. You could say: "Could I please get a cup of espresso with milk and one spoon of sugar?". Or you could write on a note: "Espresso. Milk. 1 sugar". Both get the point across, but one is more conversational, the other is more concise.
Same with LINQ. One syntax was made to look as much like SQL as possible, and the other to be more "C#-ish" and flexible. In the end, the C# compiler turns both syntaxes into the same thing: method calls. So the choice usually comes down to readability and personal taste.
Let's check out both.
2. Method Syntax
This is the style where you chain LINQ extension methods together with dots. This approach is super popular among .NET devs because it's easy to add new operations, the result is always IEnumerable<T>, and it's comfy to write right inside your code.
Example: Filter and sort products
var filteredProducts = products
.Where(p => p.Price < 1000) // Filter by price
.OrderBy(p => p.Name) // Sort by name
.ToList(); // Convert to List<Product>
Where, OrderBy, and ToList are LINQ extension methods, each returning a new data set you can keep working with.
Diagram
Why Method Syntax rocks
- Super flexible: you can easily build complex chains of many operations.
- All methods are just C# methods, and your IDE helps with autocomplete.
- Lets you do almost everything in LINQ (and even more).
Another example: get names of all users older than 18
Let's say we have a User class:
public class User
{
public string Name { get; set; }
public int Age { get; set; }
}
Now let's get the names of adult users:
List<User> users = ... // declared somewhere
var adultNames = users
.Where(u => u.Age >= 18)
.Select(u => u.Name)
.ToList();
3. Query Syntax (SQL-like syntax)
This syntax was made so C# devs would feel at home if they've worked with SQL before. It looks like a database query and starts with the from keyword.
Example: same filter and sort
var filteredProducts =
from p in products
where p.Price < 1000
orderby p.Name
select p;
Here, it reads just like a classic query: "from the products collection take p, where p.Price < 1000, order by p.Name, select p".
Diagram
Why Query Syntax rocks
- Looks like SQL, so it's easier for folks who've worked with databases.
- More readable for long queries with multiple conditions, groupings, joins (join).
Another example: get names of adult users
var adultNames =
from u in users
where u.Age >= 18
select u.Name;
Heads up: Here, right after select you can pick not the whole object, but a specific field — like just the name.
4. Comparison: Method Syntax vs Query Syntax
| Method Syntax | Query Syntax | |
|---|---|---|
| Syntax | |
|
| Looks like | Regular methods/chains | SQL |
| Where used | Always, for any operations | Not all operations available (for example, , only in Method Syntax) |
| Readability | Great for chains | Handier for groupings, joins |
| What it returns | Usually |
Usually , but sometimes you need for a list |
Fun fact from real life
Most examples in the official Microsoft LINQ docs are shown in both styles. But in production code, you’ll see Method Syntax more and more — it’s just easier when you’re chaining extension methods (Where, Select, OrderBy, etc).
Mix or not mix? Which style to pick
You can totally mix both syntaxes in one project (even in one query — but that looks weird). The main thing is not to make a code salad. Usually, folks pick one style for a whole module or project so the code is easier to read.
Method Syntax is awesome for sequential transformations and using all those LINQ methods that only exist as methods (Sum, Count, Any, and a few others).
Query Syntax is super handy for stuff with join, group by, or gnarly multi-level conditions — it wins on readability there.
5. Converting between styles: same thing, different look
LINQ inside C# turns any SQL-like query (Query Syntax) into a chain of method calls (Method Syntax). So whatever you write, C# will turn it into extension methods at compile time anyway.
Example 1 — filtering:
Query Syntax:
var adults = from u in users
where u.Age >= 18
select u;
Method Syntax (equivalent):
var adults = users.Where(u => u.Age >= 18);
Example 2 — selecting fields (Select):
Query Syntax:
var names = from u in users
select u.Name;
Method Syntax:
var names = users.Select(u => u.Name);
7. Groupings and joins (join, group by)
Creating new objects
Let's add to our learning app the ability to show a list of users grouped by age. Here, the syntax difference really stands out.
Query Syntax (grouping):
var usersByAge =
from u in users
group u by u.Age into ageGroup
select new { Age = ageGroup.Key, Users = ageGroup.ToList() };
We're grouping users by age (group u by u.Age). After into you get a variable ageGroup — that's the group itself.
Method Syntax (equivalent):
var usersByAge = users
.GroupBy(u => u.Age)
.Select(ageGroup => new { Age = ageGroup.Key, Users = ageGroup.ToList() });
Even trickier: joining (join)
Say we have a list of orders (orders) and a list of users (users). We want to get user names and their order totals.
Query Syntax:
var userOrders =
from user in users
join order in orders on user.Id equals order.UserId
select new { user.Name, order.Amount };
Method Syntax:
var userOrders = users.Join(
orders,
user => user.Id,
order => order.UserId,
(user, order) => new { user.Name, order.Amount }
);
8. Common mistakes, gotchas, and pro tips
One of the most common misconceptions: if you don't add .ToList(), the result isn't a list, it's a "lazy query" (lazy query) that only runs when you first iterate over it. That's handy, but can lead to surprises if the original collection changes after you wrote the query. We'll talk more about "deferred execution" later (after we get to know LINQ methods).
A lot of newbies get tripped up thinking you can use all LINQ methods in Query Syntax. For example, you can't just write select sum(u.Age), you have to switch to Method Syntax (users.Sum(u => u.Age)).
GO TO FULL VERSION