# What is LINQ?

LINQ is ETL for the data in your program. Start from any collection, chain methods such as Where, OrderBy and Select that each transform the items, and finish with ToList, Count or First. A query runs when its results are used.

Journeyman · C# · Updated November 3, 2026

## After this lesson you can

- Chain LINQ methods from a source, through transformations, to a result such as ToList or Count
- Explain that a LINQ query runs when its results are used, not when it's written, and use ToList to keep the results

## Key takeaways

- A LINQ chain starts from any collection, transforms it with methods such as `Where`, `OrderBy` and `Select`, and ends with a result such as `ToList()` or `Count()`.
- LINQ never changes the original collection; it always builds something new from it.
- A LINQ query runs when its results are used, such as by a `foreach` or `Count()`, not when it's written. This is deferred execution.
- End a chain with `ToList()` to keep the results as they are now, so they won't change behind your back or run the query again.

**LINQ** (*Language-Integrated Query*, said "link") is a set of methods for working with collections: filtering, sorting, reshaping, totaling. It's ETL for the data inside your program:

| ETL | In LINQ | Example |
|---|---|---|
| **Extract** from a source | Any collection: a list, an array, a set, the lines of a file | `names` |
| **Transform**, one step at a time | Methods that each pass on a changed stream of items | `.Where(...)`, `.OrderBy(...)`, `.Select(...)` |
| **Load** into a destination | A method that turns the stream back into data at rest | `.ToList()`, `.Count()`, `.First()` |

## From a loop to LINQ

Here's a job you can already do with a loop: the names longer than 4 letters, in alphabetical order, in capitals.

```csharp
List<string> names = new List<string> { "Olivia", "Ethan", "Sophia", "Liam", "Emma", "Noah", "Ava", "Jackson" };

List<string> result = new List<string>();
foreach (string name in names)
{
    if (name.Length > 4)
    {
        result.Add(name.ToUpper());
    }
}
result.Sort();

Console.WriteLine(string.Join(", ", result));
```

```text
ETHAN, JACKSON, OLIVIA, SOPHIA
```

And here's the same job with LINQ:

```csharp
List<string> names = new List<string> { "Olivia", "Ethan", "Sophia", "Liam", "Emma", "Noah", "Ava", "Jackson" };

List<string> result = names
    .Where(name => name.Length > 4)
    .OrderBy(name => name)
    .Select(name => name.ToUpper())
    .ToList();

Console.WriteLine(string.Join(", ", result));
```

```text
ETHAN, JACKSON, OLIVIA, SOPHIA
```

Read it top to bottom, like a recipe: *take the names, keep the ones longer than 4, put them in order, make each one capitals, and collect them into a list.* Each line is one step, and each step gets a lambda saying what to do with one item.

The loop says **how** to do it: make a list, loop, check, add, sort. LINQ says **what** you want, and reads almost like the sentence describing it. (It's the same thinking as SQL: `WHERE`, `ORDER BY` and `SELECT` are there for a reason.)

## The steps

- **The source** can be any collection, because LINQ's methods work on **`IEnumerable<T>`**: the *"you can go through my items one by one"* contract from *Software Interfaces*. Lists, arrays, sets, dictionaries and `File.ReadLines` all keep it. LINQ's methods come with `using System.Linq;`, which every project already has built in.
- **The transformations** each take a stream of items and hand on a new one. `Where` hands on fewer items, `OrderBy` the same items in a new order, `Select` a changed item for each one.
- **The destination** ends the chain: `ToList()` collects the items into a `List<T>`, `ToArray()` into an array, and methods such as `Count()`, `Sum()` and `First()` reduce them to one value.

The original list is never changed. LINQ always builds something new from it.

## A query runs when it's used

Here's something surprising. Without the last step, a LINQ chain doesn't **do** anything yet. It's a recipe, not a meal: it runs when something asks for its items, such as a `foreach`, `ToList()` or `Count()`.

```csharp
List<int> scores = new List<int> { 72, 95, 48 };

IEnumerable<int> passes = scores.Where(score => score >= 60);

scores.Add(88);

Console.WriteLine(passes.Count());
```

```text
3
```

`passes` was written when the list had two passing scores, but it counts 3, because the query only ran at `passes.Count()`, after 88 was added. This is called **deferred execution**: the work is put off until the results are needed.

When you want the results **now**, frozen as they are, finish with `ToList()`:

```csharp
List<int> scores = new List<int> { 72, 95, 48 };

List<int> passes = scores.Where(score => score >= 60).ToList();

scores.Add(88);

Console.WriteLine(passes.Count);
```

```text
2
```

A good habit: end a chain with `ToList()` (or `Count()`, `First()`, …) unless you have a reason not to. Then the result is data at rest, and it won't change behind your back or run the query again every time you loop over it.

## Check yourself

2 questions to try on the lesson page.

## So what

LINQ turns *"make a list, loop, check, add"* into one readable sentence: source, transformations, destination. It's how most C# code works with collections, and the same methods will query a database through Entity Framework Core later in this module.

## Key terms

- [LINQ](https://www.ask-codey.com/glossary/linq)
- [IEnumerable&lt;T>](https://www.ask-codey.com/glossary/ienumerable-t)
- [Deferred Execution](https://www.ask-codey.com/glossary/deferred-execution)

## Cheat sheets

- [What is LINQ?](https://www.ask-codey.com/cheat-sheets/linq-what-is-linq-cheat-sheet)

Source: https://www.ask-codey.com/lessons/linq-what-is-linq
