Skip to Content
Course content

34: LINQ Query and Method Syntax

Click on the "Edit" button in the top corner of the screen to edit your slide content.

A few years ago, I was reviewing a pull request from a junior dev who was trying to filter a list of active subscriptions based on a set of complex business rules. He had written about forty lines of code: nested foreach loops, multiple temporary List<T> objects to hold intermediate results, and a tangle of if statements. It worked, but it was a nightmare to read. I remember showing him how to do the exact same thing in three lines of LINQ. The look of absolute disbelief on his face—followed by the realization that he'd spent four hours writing something that could be a single expression—is why I love teaching this topic.

The Declarative Nature of Query Syntax

When you first see LINQ Query Syntax, it feels like someone smuggled SQL into C#. It's a declarative style, meaning you describe what you want to happen rather than how to loop through the memory. You start with from, apply filters with where, and finish with a select.

Imagine we have a list of Employee objects and we only want the names of people in the "Engineering" department who earn more than $80,000. In query syntax, it looks like this:

var highEarners = from emp in employees
                   where emp.Department == "Engineering" && emp.Salary > 80000
                   select emp.FullName;

I find that query syntax is often more readable when you're dealing with complex joins or grouping. It reads like a sentence, which makes it easier for another developer (or you, six months from now) to understand the intent of the filter without tracing loop counters.

Chaining Logic with Method Syntax

While query syntax is elegant, you'll find that most professional C# codebases lean heavily on Method Syntax. This is the "fluent" approach where you chain extension methods together using lambda expressions. It's more compact and, more importantly, it gives you access to a much wider array of LINQ operators that aren't available in the query-style syntax—like .First(), .Any(), or .Distinct().

That same employee filter looks like this using method syntax:

var highEarners = employees
    .Where(emp => emp.Department == "Engineering" && emp.Salary > 80000)
    .Select(emp => emp.FullName);

Notice the => (lambda operator). You're essentially passing a tiny, anonymous function into the Where method. The Where method handles the looping logic internally; you just provide the rule. It's a shift in mindset from "Iterate through this list" to "Filter this stream of data."

Choosing the Right Tool for the Job

Here is a secret: the C# compiler actually translates query syntax into method syntax before the code is ever run. They are functionally identical in terms of performance. So, why have both? It comes down to readability and capability.

I usually follow these rules of thumb:

  • Use Query Syntax when you are performing complex joins or when the query is so long that the "SQL-like" structure makes it easier to scan.
  • Use Method Syntax for almost everything else. If you just need to filter a list, find a single element, or transform a few properties, method chaining is faster to write and more common in the industry.

Don't feel like you have to pick a "side" and stick to it religiously. In a single file, you might use a query for a complex data retrieval and a simple .Any() call to check if the result set is empty. The goal is clarity, not consistency for the sake of consistency.




📋 Practical Task

Building a High-Value Order Filtering System

You are working on a warehouse management system. You have a list of Order objects, where each order has an OrderId (int), a CustomerName (string), a TotalAmount (decimal), and a IsShipped (bool) property.

Your task is to create a feature that identifies "Priority Pending Orders." Write a piece of code that does the following:

  • Filters the list to find orders that have not been shipped (IsShipped == false).
  • Further filters those orders to only include those with a TotalAmount greater than $500.
  • Sorts the resulting orders by TotalAmount in descending order.
  • Returns only the CustomerName of these orders.

Requirement: Implement this logic twice—once using Query Syntax and once using Method Syntax—to ensure you are comfortable switching between the two patterns.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.