A quick guide to LINQ with examples
Tags: tutorial, csharp, beginners, dotnet
Published: 2021-02-01 15:46:28

_I originally posted an extended version of [this on my blog](https://canro91.github.io/2021/01/18/LinqGuide/). It's part of a series about LINQ and other C# features._

Today a friend asked me about LINQ. I guess she was studying for a technical interview. So, dear Alice, this is what LINQ is and these are the most common LINQ methods with examples in C#.

**Language-Integrated Query (LINQ) is the declarative way of working with collections in C#. LINQ works with databases and xml files, too. The most common LINQ methods are: `Where`, `Select`, `Any` `GroupBy` and `FirstOrDefault`. LINQ has an API syntax, extensions methods on the `IEnumerable` type, and a query syntax, a SQL-like syntax.**

## 1. LINQ is declarative

**LINQ is declarative.** It means you write your code stating the results you want, instead of doing every step to get those results.

With LINQ, you write code to _"filter a collection based on a condition"_. Instead of writing code to _"grab an element, check if it satisfies a condition, then move to the next element, check again..."_, etc.

LINQ is a better alternative to query collections using `for`, `foreach` or any other loop. Because, with LINQ you can write more expressive and compact code.

<figure>
<img src="https://images.unsplash.com/photo-1524985069026-dd778a71c7b4?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=400&ixid=MXwxfDB8MXxhbGx8fHx8fHx8fA&ixlib=rb-1.2.1&q=80&utm_campaign=api-credit&utm_medium=referral&utm_source=unsplash_source&w=800" alt="Waiting at a cinema before a movie starts" />

<figcaption><span>Photo by <a href="https://unsplash.com/@ewitsoe?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Erik Witsoe</a> on <a href="https://unsplash.com/?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></span></figcaption>
</figure>

### Our first example: Movies

Let's see an example. Let's start with the collection of movies we have watched. We have a `Movie` class with a name, release year and rating. Let's find our favorite movies, the ones with rating greater than 4.5.

This is a console program to print our favorite movies. Let's use [records and top-level statements from recent C# versions](https://canro91.github.io/2021/09/13/TopNewCSharpFeatures/).

```csharp
var movies = new List<Movie>
{
    new Movie("Titanic", 1998, 4.5f),
    new Movie("The Fifth Element", 1997, 4.6f),
    new Movie("Terminator 2", 1991, 4.7f),
    new Movie("Avatar", 2009, 5),
    new Movie("Platoon", 1986, 4),
    new Movie("My Neighbor Totoro", 1988, 5)
};

var favorites = new List<Movie>();
foreach (var movie in movies) // 👈
{
    if (movie.Rating > 4.5) // 👈
    {
        favorites.Add(movie);
    }
}

foreach (var favorite in favorites)
{
    Console.WriteLine($"{favorite.Name}: [{favorite.Rating}]");
}

// Output:
// The Fifth Element: [4.6]
// Terminator 2: [4.7]
// Avatar: [5]
// My Neighbor Totoro: [5]

Console.ReadKey();

record Movie(string Name, int ReleaseYear, float Rating);
```

Notice the `foreach` loop and the comparison using an `if` statement to look for ratings greater than 4.5.

> _Change the example to use your own movies and see which ones are your favorites!_

### Our first LINQ method: Where

LINQ methods are extension methods on the `IEnumerable` type. This type represents objects we can loop through, like, arrays, lists, dictionaries, among others.

To work with LINQ, you need to be comfortable with [delegates and lambda functions](https://canro91.github.io/2019/03/22/WhatTheFuncAction/). A delegate is a reference to a method. And, a lambda function is a method with only the parameters and the body.

Now, to the actual example. We want to filter our list of movies to keep only the ones with rating greater than 4.5. The LINQ method to filter collections is `Where`.

**The LINQ `Where` method returns a new collection with all the elements that meet a condition.**

Let's replace the `foreach` statement from our first example with the `Where` method. And, let's use the condition inside the `if` statement as the filter condition for the `Where` method. Our example looks like this:

```csharp
var movies = new List<Movie>
{
    new Movie("Titanic", 1998, 4.5f),
    new Movie("The Fifth Element", 1995, 4.6f),
    new Movie("Terminator 2", 1999, 4.7f),
    new Movie("Avatar", 2010, 5),
    new Movie("Platoon", 1986, 4),
    new Movie("My Neighbor Totoro", 1988, 5)
};

var favorites = movies.Where(movie => movie.Rating > 4.5);
//                     👆👆
foreach (var favorite in favorites)
{
    Console.WriteLine($"{favorite.Name}: [{favorite.Rating}]");
}

Console.ReadKey();

record Movie(string Name, int ReleaseYear, float Rating);
```

We replaced the `foreach` and `if` statements with a single line of code:

```csharp
var favorites = movies.Where(movie => movie.Rating > 4.5);
```

More compact, isn't it? Also, we turned the condition inside the `if` statement into a lambda function. Instead of lambda functions, you could use private methods too.

**LINQ methods don't change the original collection.** They return a result without modifying the original collection. From our example, when we used the `Where` method, it returned a new collection. It didn't remove any elements from the original `movies` list.

## 2. Most common LINQ methods

So far, we have seen only one LINQ method, `Where`. Let's see other common methods.

### 1. Select

**With `Select`, you can transform every element of a collection.** It applies a function on every element.

Let's find only the names of our favorite movies.

```csharp
var favorites = movies.Where(movie => movie.Rating > 4.5)
                      .Select(movie => movie.Name);
                      // 👆👆

foreach (var name in favorites)
{
    Console.WriteLine(name);
}

// The Fifth Element
// Terminator 2
// Avatar
// My Neighbor Totoro
```

Notice, how this time we have nested two LINQ methods. The result from `Where` will be the input of `Select`.

For more readability, we often align the nested LINQ methods vertically by the (.) dot.

### 2. Any

**The `Any` method check if a collection is empty.** Also, it checks if a collection has at least one element matching a condition. It returns either `true` or `false`. It doesn't return a new collection.

Let's see if we have watched movies with a low rating.

```csharp
var hasAnyMovies = movies.Any();
// true

var hasBadMovies = movies.Any(movie => movie.Rating < 2);
// false
```

### 3. GroupBy

**`GroupBy` groups the elements of a collection based on a key.** It returns a collection of "groups"  or "buckets" organized by a key.

Let's group our movies by rating.

```csharp
var groupedByRating = movies.GroupBy(movie => movie.Rating); // 👈

foreach (var group in groupedByRating)
{
    Console.WriteLine($"Rating: {group.Key}");

    foreach (var movie in group)
    {
        Console.WriteLine($"{movie.Name}");
    }
    Console.WriteLine();
}

// Output:
// Rating: 4.5
// Titanic
//
// Rating: 4.6
// The Fifth Element
//
// Rating: 4.7
// Terminator 2
//
// Rating: 5
// Avatar
// My Neighbor Totoro
//
// Rating: 4
// Platoon
```

Also, **`GroupBy` allows you to transform each group.** This time, let's count the movies with the same rating.

```csharp
var groupedByRating = movies.GroupBy(movie => movie.Rating,
                                    (rating, movies) => new // 👈
                                    {
                                        Rating = rating,
                                        Count = movies.Count()
                                    });

foreach (var group in groupedByRating)
{
    Console.WriteLine($"{group.Rating}: [{group.Count}]");
}

// Output:
// 4.5: [1]
// 4.6: [1]
// 4.7: [1]
// 5: [2]
// 4: [1]
```

Notice the second parameter of the `GroupBy`. It's a `Func` with the key and the elements of each group. We also used an anonymous object `new { Rating=..., Count=... }`. It's like a regular object, but we didn't specify a name.

### 4. First and FirstOrDefault

**`First` and `FirstOrDefault` return the first element in a collection.** `First` throws an exception if the collection is empty. Unlike `First`, `FirstOrDefault` returns a default value if the collection is empty.

Also, `First` and `FirstOrDefault` return the first element matching a condition.

Let's find the oldest movie we have watched.

```csharp
var oldest = movies.OrderBy(movie => movie.ReleaseYear)
                   .First(); // 👈

// Platoon
```

This time, we used the `OrderBy` to sort the movies collection by release year. To then, grab the first one. Two examples for the price of one!

In the same spirit of `First` and `FirstOrDefault`, you have `Last` and `LastOrDefault`. But, they return the last element instead of the first one.

## 3. Cheatsheet

There are more LINQ methods than the ones we've seen so far. These are some of them.

| Method | Function |
|---|---|
| `Where` | Filter a collection |
| `Select` | Transform every element of a collection | 
| `Any` | Check if a collection is empty | 
| `Count` | Count all elements of a collection |
| `Distinct` | Find the unique elements of a collection |
| `GroupBy` | Group the elements of a collection based on a key | 
| `OrderBy` | Sort a collection based on a key  |
| `First` | Find the first element of a collection. Throw if the collection is empty | 
| `FirstOrDefault` | Same as `First`, but it returns a default value if it's empty | 
| `Last` | Find the last element of a collection. Throw if the collection is empty |
| `LastOrDefault` | It returns a default value if it's empty, instead |
| `Single` | Find only one element in a collection matching a condition. Throw, otherwise |
| `SingleOrDefault` | It returns a default value if there isn't one matching element, instead |
| `Take` | Pick the first _n_ consecutive elements of a collection |
| `TakeWhile` | Pick the first consecutive elements that satisfy a condition |
| `Skip` | Return a collection without the first _n_ consecutive elements |
| `SkipWhile` | Return a collection without the first consecutive elements that satisfy a condition |
| `Sum` | Sum the elements of a collection |
| `Min`, `Max` | Find the smallest and largest element of a collection |
| `ToDictionary` | Convert a collection into a dictionary |

Voilà! That's it, Alice. That's all you need to know to start working with LINQ in your code in less than 15 minutes. With LINQ you can write more compact and expressive code. The next time you need to write logic using loops, give LINQ a try!

***

_Hey! I'm Cesar, a software engineer and lifelong learner. If you want to learn more about this subject, check my course [Getting Started with LINQ](https://bit.ly/csarag-linq-course) on Educative where I cover other LINQ methods in depth._

_Happy LINQ time!_