← Open in the full interactive course (progress tracking, search & more)

LINQ lets you ask a question about your data — instead of writing a loop that manually figures out the answer.

You already know how to loop. You've written foreach loops that filter items with an if, build up a new list, and sum or count things along the way. That skill works everywhere — but it's also verbose. Every time you want "the expensive products, sorted by name" you write a new hand-rolled loop, and the actual intent — "give me the expensive products, sorted by name" — gets buried inside bookkeeping code: an empty list, an if, an Add, a comparer.

LINQ (Language Integrated Query) is a set of tools built directly into C# and .NET that lets you express that intent directly, as a query, instead of writing the loop that carries it out by hand. This lesson introduces what LINQ is, the problem it solves, and previews its two syntaxes — the rest of this module goes deep on every piece.

What Is It?

The Simple Explanation

LINQ stands for Language INtegrated Query. It's a uniform way to filter, transform, sort, group, and summarize data — collections in memory, XML, and (through a separate provider) databases — using the same small vocabulary of operators, no matter what the data actually is or where it lives.

Instead of writing "loop through this, check that condition, build a new list," you write "from this data, where this condition, select this shape" — and .NET does the looping for you.

The Technical Definition

Technically, LINQ is a set of extension methods — Where, Select, OrderBy, GroupBy, Sum, and dozens more — defined in System.Linq on IEnumerable<T> (and, separately, on IQueryable<T>, covered in the next lesson). Because you learned in Foundations that every collection — arrays, List<T>, Dictionary<TKey,TValue>, HashSet<T>, and any custom type — implements IEnumerable<T>, every one of those types gets the entire LINQ vocabulary for free, automatically, the instant you add using System.Linq; to a file.

Built On What You Already Know

LINQ isn't a new language feature bolted on top of C# — it's a library of methods that take an IEnumerable<T> and hand back another IEnumerable<T> (or a single value). Because it's "just methods," everything you already know about generics, Func<T,TResult>, Predicate<T>, and lambda expressions from the Intermediate module applies directly — a LINQ call like Where(p => p.Price > 50) is a method call that takes a lambda, exactly like any other method that accepts a Func<T,bool>.

Why Does It Exist?

The Problem — Manual Loops Bury Intent in Mechanics

Say you have a list of products, and you need the names of every product that's in stock and costs more than $50, sorted cheapest first. Written by hand, that's a small piece of logic wrapped in a lot of scaffolding:

var results = new List<string>(); foreach (var product in products) { if (product.Stock > 0 && product.Price > 50) { results.Add(product.Name); } } results.Sort((a, b) => { var pa = products.First(p => p.Name == a).Price; var pb = products.First(p => p.Name == b).Price; return pa.CompareTo(pb); }); foreach (var name in results) Console.WriteLine(name);

Nothing here is wrong — but notice what you had to write to express one simple idea: an empty list to accumulate into, an if for the filter, an Add call, and then a fairly awkward custom sort because you sorted names but needed to sort by price. The actual question — "which in-stock products over $50, cheapest first?" — is buried under fifteen lines of bookkeeping.

The Solution — Say What You Want, Not How to Loop

LINQ collapses that entire block into a single, readable pipeline:

var results = products .Where(p => p.Stock > 0 && p.Price > 50) .OrderBy(p => p.Price) .Select(p => p.Name); foreach (var name in results) Console.WriteLine(name);

This reads almost like English: "from products, where in stock and price over 50, order by price, select the name." No accumulator list, no manual comparer, no separate loop for sorting. The intent is the code — that's the entire point of LINQ.

Big Picture — Before vs After

WITHOUT LINQ vs WITH LINQ
WITHOUT LINQ
Create empty list

Loop over source

Check condition manually

Add to list manually

Sort with a custom comparer

Loop again to project a shape
WITH LINQ
.Where(...) — describe the filter

.OrderBy(...) — describe the order

.Select(...) — describe the shape

.NET builds and runs the loop for you
Same result. One version describes what; the other hand-codes how.

How It Works

FROM A LINQ CHAIN TO A RESULT
1. START WITH A SOURCE
2. CHAIN LINQ OPERATORS
3. ENUMERATE THE RESULT

Simple Example

The dataset below — a small product catalog — will reappear throughout this module, so you see the same data queried in different ways as you learn each operator.

public record Product(int Id, string Name, string Category, decimal Price, int Stock); List<Product> products = [ new(1, "Wireless Mouse", "Electronics", 24.99m, 120), new(2, "Mechanical Keyboard", "Electronics", 89.99m, 0), new(3, "Standing Desk", "Furniture", 349.00m, 15), new(4, "Desk Lamp", "Furniture", 19.50m, 60), new(5, "Noise-Cancelling Headphones", "Electronics", 199.99m, 8), new(6, "Office Chair", "Furniture", 259.00m, 0), ]; // Manual loop var expensive1 = new List<string>(); foreach (var p in products) if (p.Price > 50 && p.Stock > 0) expensive1.Add(p.Name); // LINQ — same result var expensive2 = products .Where(p => p.Price > 50 && p.Stock > 0) .Select(p => p.Name) .ToList(); // Both print: Noise-Cancelling Headphones

Code → Meaning → Result: Where keeps only the products matching the condition; Select transforms each surviving Product into just its Name; ToList() forces the result into a concrete List<string>. Same outcome as the hand-written loop, in a third of the code.

Real-World Example

An admin dashboard for an e-commerce store needs a "low stock alert" panel: any product with fewer than 10 units left, sorted by how urgent the shortage is (fewest units first), showing just the name and stock count. Without LINQ, that's a filter, a sort, and a projection, each requiring its own loop or careful merging. With LINQ, it's one pipeline:

var lowStockAlerts = products .Where(p => p.Stock < 10) .OrderBy(p => p.Stock) .Select(p => new { p.Name, p.Stock }); foreach (var item in lowStockAlerts) Console.WriteLine($"{item.Name}: only {item.Stock} left"); // Mechanical Keyboard: only 0 left // Office Chair: only 0 left // Noise-Cancelling Headphones: only 8 left

This exact shape — filter, sort, project — is one of the most common patterns in real applications: reporting screens, search results, admin panels, and API endpoints all repeatedly need "some of the data, reshaped, in some order." LINQ turns that recurring pattern into a one-line habit instead of a fresh loop every time.

Analogy

Ordering at a Restaurant vs Cooking Yourself

A hand-written loop is like cooking a meal entirely yourself: you go to the market, pick ingredients, chop them, combine them in the right order, and plate the result — every single step is your responsibility, and one wrong step ruins the dish.

LINQ is like ordering from a menu: "the salmon, medium, with a side salad" describes the outcome you want. The kitchen — .NET's LINQ implementation — knows how to actually produce it. You're not forbidden from cooking yourself (a hand-loop is still valid C#), but for the vast majority of everyday "filter, sort, shape" tasks, ordering from the menu is faster to write and easier to read.

Under the Hood

TWO SYNTAXES, ONE ENGINE — A PREVIEW
1. METHOD SYNTAX — THE FLUENT CHAIN YOU'VE SEEN ABOVE
products.Where(p => p.Price > 50).Select(p => p.Name);
2. QUERY SYNTAX — A SQL-LIKE ALTERNATIVE FOR THE SAME QUERY
from p in products
where p.Price > 50
select p.Name;
3. THE COMPILER TRANSLATES QUERY SYNTAX INTO METHOD SYNTAX

Common Confusion

1. "LINQ is a database technology" — no, it's a general query library

Many developers first meet LINQ through Entity Framework and assume it's inherently about databases. It isn't. LINQ started as, and still is, primarily a way to query in-memory collections (this is called "LINQ to Objects," and it's what this entire module focuses on). Databases are just one more source LINQ can target, through a separate provider — that's the subject of the next lesson and, in full, of Intermediate Part VI.

2. "LINQ replaces loops entirely" — it doesn't, and shouldn't

LINQ is a powerful default for "filter, transform, sort, aggregate" tasks — but a plain foreach is still the right tool for side-effecting work (like sending an email per item) or performance-critical hot paths. This module's closing lesson, LINQ Performance, covers exactly where the trade-off lies.

Common Mistakes

Mistake 1 — Forgetting using System.Linq;

Without this using directive, none of the extension methods (Where, Select, etc.) appear on your collections at all — you'll get a compiler error saying the method doesn't exist. Add using System.Linq; at the top of the file (most new project templates include it via global usings already).

Mistake 2 — Reaching for a loop out of habit, for something LINQ expresses more clearly

Writing a five-line loop with an accumulator list for a simple filter-and-project is no longer necessary once you know LINQ. Recognize the "filter / transform / sort / aggregate" shape and reach for the matching operator instead — that recognition skill is exactly what this module builds.

When Should I Use It?

Reach for LINQ when

A plain loop may still be better when

Mental Model

Loop = "here's exactly how to walk through this and build the answer"
LINQ = "here's what answer I want; you figure out the walking"

Remember:
· LINQ is just extension methods on IEnumerable<T> — nothing magic, nothing new to the runtime.
· Method syntax (.Where().Select()) and query syntax (from...where...select) are the same thing, compiled the same way.
· This lesson is the front door — every operator you saw in passing here gets its own full lesson in this module.

Key Takeaway


Check Your Understanding

You've seen what LINQ is and why it exists. Let's check your understanding before diving into the individual operators.

1. What does LINQ fundamentally provide?

Show answer

Correct: B

Why B is correct: LINQ is a library of extension methods layered on top of IEnumerable<T> (and IQueryable<T>). It's ordinary C#, not a new language.

Why A is incorrect: LINQ is integrated into C# via method and optional query syntax — it isn't a separate language, and it's not database-specific.

Why C is incorrect: LINQ doesn't touch the type system; it's just methods you call.

Why D is incorrect: LINQ to Objects (this module's focus) works entirely in memory, with no database involved at all.

Reinforcement: LINQ is "just methods" — which is exactly why it works on every IEnumerable<T> you already know.

2. Why does every collection type — arrays, List<T>, Dictionary<TKey,TValue> — automatically get access to LINQ operators like Where and Select?

Show answer

Correct: B

Why B is correct: LINQ methods extend IEnumerable<T>. Any type implementing that interface — which is every standard collection, plus any custom enumerable type — gets the whole vocabulary automatically.

Why A is incorrect: There's no special-casing; it's ordinary extension method resolution, the same mechanism as any other extension method.

Why C is incorrect: No such base class exists — collections share a common interface, not a common base class.

Why D is incorrect: Method-syntax LINQ operators (Where, Select) are ordinary methods, not language keywords — only query syntax (from/where/select) involves actual C# keywords.

Reinforcement: This is the same "shared contract, universal behavior" idea from IEnumerable<T> that you learned back in Foundations — LINQ is the payoff for that design.

3. What is the main advantage LINQ offers over a hand-written foreach loop for a filter-then-sort-then-project task?

Show answer

Correct: B

Why B is correct: As the before/after comparison showed, the value of LINQ here is readability and intent, not raw speed — the same idea, expressed with far less scaffolding.

Why A is incorrect: LINQ is not inherently faster than a well-written loop, and can sometimes be marginally slower due to delegate and iterator overhead — a topic covered fully in this module's closing lesson.

Why C is incorrect: LINQ operators rely heavily on lambda expressions — they don't remove them, they use them as arguments.

Why D is incorrect: Standard LINQ to Objects runs sequentially by default; parallelism requires the separate, explicitly-opted-into PLINQ (AsParallel()), not covered in this introductory lesson.

Reinforcement: LINQ's core value proposition is clarity of intent, not automatic performance wins.

4. Which statement correctly describes the relationship between LINQ's method syntax and query syntax?

Show answer

Correct: C

Why C is correct: As previewed in "Under the Hood," from...where...select is translated by the compiler into calls like .Where(...).Select(...) — they produce identical code.

Why A is incorrect: They aren't separate features — one compiles directly into the other, which lessons 119 and 120 cover in detail.

Why B is incorrect: Both syntaxes work identically on in-memory collections and on database-backed IQueryable<T> sources — neither is restricted to one or the other.

Why D is incorrect: Neither syntax is deprecated; method syntax is simply more commonly used day-to-day, as you'll see later in this module.

Reinforcement: Two syntaxes, one engine — that equivalence is the key idea to carry forward into the rest of this module.

You now understand what LINQ is and why it exists. Next up: the distinction between IEnumerable<T> and IQueryable<T> — two very different kinds of "queryable" data.


dotnetmadeeasy.com — Learn C# and .NET, the right way.