
This course includes our updated coding exercises so you can practice your skills as you learn.
See a demo
Welcome! Let's learn everything we need to know to start working productively with LINQ. The best of all C# features ever. Fire up your Visual Studio or favorite IDE, download the companion source code, and let's get started to manipulate collections with LINQ.
Let's start by defining what LINQ is.
Before covering what makes LINQ different from loops, let's use our first LINQ method to filter collections: Where.
LINQ is a set of extension methods on the IEnumerable type. Let's learn about the IEnumerable and its related IEnumerator type.
LINQ is not a new C# feature. It's available since the early versions of the classical .NET framework back in the 2010s. If you're using the .NET Framework, the classical one, your code will look different.
We need extension methods because LINQ uses extensions methods on the IEnumerable type. And, we will find extension methods handy for our projects too. Let's learn how to write extension methods.
To work with LINQ, we need to be comfortable writing delegates. Let's learn about them.
To write LINQ queries, we can use a method inside Where and other LINQ methods. But most of the time, we use lambda expressions to write LINQ queries.
It's time to practice what we've covered so far. After watching the instructions, try to solve the exercise on your own. After a 3-second countdown, we go together through a solution.
When we write LINQ queries, we use a declarative style of programming. This is one of the differences between LINQ and loops.
Let's learn what happens to input collections when working with LINQ.
Let's learn about another LINQ feature: lazy evaluation.
Let's take a moment to summarize what we've covered so far.
LINQ has more methods, not only the Where method. Let's learn how to transform a collection with Select.
The Select method has another overload that we can use to transform every element with its position in the result collection.
Let's learn how to use the Any and All methods to check whether a collection has elements or not. Unlike Select and Where, these two methods don’t return a new collection, but a bool.
Let's learn how to group the elements of a collection by a single key.
Also, the GroupBy method transforms each group or bucket of elements.
With GroupBy, we can group the elements of a collection by more than one grouping property.
Let's use an anonymous object as the grouping key inside GroupBy.
GroupBy doesn't sort the element of a collection. For that, we need another LINQ method: OrderBy.
With Where, we filter a collection and get another collection back. But what about if we want to find only one element? We need the methods First and FirstOrDefault.
These ones are similar to First and FirstOrDefault. But instead of finding the first element, they find find the last one.
Similar to First, Last, and their alternatives with OrDefault, LINQ has another pair of methods: Single and SingleOrDefault. But, these two expects one and only one matching element.
What if we want to use First and Last, but we need more than one element? We need Take and Skip instead.
It's time to put into practice what we've covered so far. Write a method that displays a collection in pages.
Let's practice refactoring three methods to use LINQ instead of logic with foreach and if. This is a common task when maintaining and improving legacy codebases.
So far, we have use LINQ methods that expect any type. We've been using Movie. But these three LINQ methods receive as a parameter a delegate that returns a number. Sum, Min, and Max...Ah, by the way, there's an Average too.
Select transforms every element of a collection. There's a similar method to transform the elements of a collection: SelectMany. But, there's a difference between them.
This is an easy one. Distinct finds the "unique" elements of a collection.
This time, let's use two catalogs of movies: mine and yours. And let's find the union, intersection, and "difference" between them. Similar to the Math operations, LINQ has three methods: Intersect, Union, and Except.
Let's build some sort of analytics for future directors. Let's use LINQ to answer three questions about a sample of 50 movies from the Internet Movie Database (IMDb).
This is a less common LINQ method. We won't use it everyday but it's handy from time to time. Let's learn how to apply a function to a collection carrying the result with Aggregate.
So far, we've used LINQ methods as extension methods on the IEnumerable type. But there's another way to find LINQ apart from extension methods: query syntax. It's good to know about it, but we get our backs covered using extension methods. They're more common.
Hey, we've covered a lot. Let's take a moment to recap what we covered in this section.
Don't forget to download a cheatsheet with the five most common LINQ methods in pictures. You will find it in the "Resources" tab for this lesson.
So far, we've covered what makes LINQ different from loops and the most common LINQ methods. It's time to learn the most common mistakes we make when using LINQ for the first time and how to fix them.
Let's start by using the right methods to filter a collection and to check if it has the elements we want.
If FirstOrDefault and similar OrDefault methods don't find matching elements, they return the default value of the type we have in our collection. For objects, the default value is null. And when we try to access properties and methods of null objects, bad things happen.
LINQ doesn't cache the result of our queries. Often, by mistake, we expect that and our LINQ queries end up being evaluated multiple times.
Now, it's time to refactor a block of code that contains the mistakes we've covered so far. Before I forget, this block throws a NullReferenceException.
Let's take a moment to summarize what we covered in this section.
When we need to check if a value belongs to a set of valid options, we use an if statement with comparisons using the OR (||) operator. Let's use Any to refactor that.
Let's say we want to find the first value different from null from multiple choices. C# has operators like the null-coalescing operator (??) for that. But, since this is a course about LINQ, let's use FirstOrDefault instead.
Validating a complex object against a set of rules is an every day task. Let's use LINQ to validate an object instead of using if statements.
It's time to put into practice those refactorings. Let's refactor a function to accept movie recommendations.
It's time to recap what we covered in this section.
LINQ is a feature that simply works. We have it since the early versions of C#. But starting from .NET 6.0, we have new LINQ methods and overloads. Let's cover some of them. Let's start with Chunk.
With Distinct, we find the "unique" values in a collection. But, to find the object containing those "unique" values, we need DistinctBy. Similar to DistinctBy, LINQ has new alternatives to existing methods such as MinBy, MaxBy, ExceptBy, IntersectBy, and UnionBy.
Starting from C# 8.0, C# has two new operators: the index from end operator (^) and the range operator (..). With these two new operators, we retrieve an "slice" of an array. And starting from .NET 6.0, Take has a new overload that receives ranges.
When OrDefault methods don't find matching elements, they return the default value of the collection. That could be a null when the collection contains reference types. Now OrDefault methods have an overload to return a custom default value instead.
For this one, we need .NET 9.0 installed. Now LINQ combines GroupBy and Count into a single method: CountBy.
Select has an overload that also returns the index of elements in the result collection. LINQ has encapsulated that behavior in a new method: Index. For this one, we need .NET 9.0 too.
Let's take a moment to summarize what we covered in this section.
If you have reached this point, congrats. I hope you have learned how to start using LINQ productively. Let's summarize what we covered in this course.
Collections are everywhere. Comments in a post, purchased items in an invoice, and guests in a hotel reservation.
We often work with these collections using for, foreach, and other loops. But C#, has a feature specifically designed for working with collections:
Language Integrated Query (LINQ).
With LINQ, you filter, transform, and query collections, using more concise and readable code than traditional loops.
This is the one C# feature you can't ignore. In fact, it's the best of all C# features. Ever.
What you will learn?
In this course, we're covering everything you need to know to start working productively with LINQ, in less than 2 hours.
After taking this course, you will:
Understand the key differences between LINQ and loops.
Learn the most frequently used LINQ methods for working with collections.
Identify and fix common mistakes when using LINQ.
Refactor away from conditionals using LINQ.
Explore the latest LINQ methods and overloads from recent .NET versions.
LINQ works with XML files and database records too. But, in this course, we're focusing on LINQ and collections like arrays and lists.
Think of this course like the 20% of the LINQ features you're using 80% of the time (That's the Pareto Principle, by the way).
In this course, we're not covering every single LINQ method out there, but the most frequently used ones. And that's on purpose. In our every day coding (and jobs) we keep using a handful of methods most of the time.
Who is this course for?
If you're a beginner C# developer who want to write more compact and expressive code when working with collections, this course is for you.
You should be comfortable declaring and initializing C# objects and working with conditionals, loops, and collections such as arrays and lists.
By the end of this course, you'll be ready to productively manipulate collections with LINQ.
See you in the first lesson.