LINQ (Language Integrated Query) is one of the most powerful features in C#. It lets you filter, sort, group, transform, and query data using clean, readable syntax – all without writing loops, temporary lists, or messy boilerplate code.
Whether you’re new to C#, preparing for interviews, or learning modern .NET development, this tutorial gives you everything you need to master LINQ from scratch.
Youβll learn what LINQ is, why it exists, how each operator works, when to use which method, and see over 60 practical examples.
Letβs begin.
π₯ What Is LINQ and Why Does It Exist?
LINQ = Language Integrated Query
Itβs a set of features in C# that lets you query data using a unified, consistent syntax.
It works over:
- Arrays
- Lists
- Dictionaries
- Databases (via Entity Framework)
- XML
- JSON
- Files
- Anything that implements
IEnumerable<T>orIQueryable<T>
Why It Exists
Before LINQ, you had to write loops for everything:
List<int> evens = new List<int>();
foreach (var n in numbers)
{
if (n % 2 == 0)
evens.Add(n);
}
With LINQ:
var evens = numbers.Where(n => n % 2 == 0);
Cleaner. Faster to write. Less error-prone.
π₯ LINQ Syntax: Method Syntax vs Query Syntax
LINQ has two styles:
1. Method Syntax (Most common)
Uses extension methods like .Where(), .Select(), .OrderBy().
var result = numbers.Where(n => n > 10).Select(n => n * 2);
2. Query Syntax (SQL-like)
Great for readability, especially grouping:
var result =
from n in numbers
where n > 10
select n * 2;
Both produce the same result.
π₯ The 12 Essential LINQ Operators
These are the operators beginners must master first.
β 1. Where β Filtering
Filters a sequence based on a condition.
var adults = people.Where(p => p.Age >= 18);
What it does:
- Returns only items where the predicate is true
- Deferred execution: it runs only when you enumerate it
β 2. Select β Transformation / Projection
Transforms each item into a new form.
var names = people.Select(p => p.Name);
Use it to:
- pick properties
- create new objects
- calculate values
Example:
var summaries = people.Select(p => new { p.Name, p.Age });
β 3. OrderBy / OrderByDescending
Sorts sequences.
var sorted = people.OrderBy(p => p.LastName);
var sortedDesc = people.OrderByDescending(p => p.Age);
Multiple sort levels:
var sorted = people
.OrderBy(p => p.LastName)
.ThenBy(p => p.FirstName);
β 4. Take / Skip
Pagination tools.
var first10 = items.Take(10);
var page2 = items.Skip(10).Take(10);
β 5. First, FirstOrDefault
Gets the first item.
var first = nums.First();
var safe = nums.FirstOrDefault();
FirstOrDefault returns:
default(T)if no items exist- e.g., null for reference types
β 6. Single, SingleOrDefault
Ensures exactly one matching item.
var user = users.Single(u => u.Id == 5);
Throws if:
- 0 items OR
- more than 1 item matches
β 7. Any β Checks if any item matches
bool hasAdults = people.Any(p => p.Age >= 18);
Fast and efficient.
β 8. All – Every item must match
bool allAdults = people.All(p => p.Age >= 18);
β 9. Count – Counts items
int total = people.Count();
int adults = people.Count(p => p.Age >= 18);
β 10. Sum, Min, Max, Average
var sum = nums.Sum();
var average = nums.Average(n => n.Score);
β 11. Distinct – Removes duplicates
var unique = numbers.Distinct();
For objects you may need .DistinctBy(p => p.Id).
β 12. SelectMany β Flattening
Flattens nested collections.
var allBooks = libraries.SelectMany(lib => lib.Books);
π₯ Practical Examples for Beginners
These examples help you understand how LINQ works on real-world data.
Weβll use this list:
var people = new List<Person>
{
new("James", 58),
new("Sarah", 32),
new("Emily", 25),
new("John", 17)
};
Example: Get all adults
var adults = people.Where(p => p.Age >= 18);
Example: Get names only
var names = people.Select(p => p.Name);
Example: Sorted by age
var sorted = people.OrderBy(p => p.Age);
Example: Does anyone under 18 exist?
bool hasChildren = people.Any(p => p.Age < 18);
Example: Count adults
int count = people.Count(p => p.Age >= 18);
Example: Build a simple report
var report = people
.OrderByDescending(p => p.Age)
.Select(p => $"{p.Name} is {p.Age} years old");
π₯ Grouping in LINQ
Grouping is one of the most powerful LINQ features.
Example dataset:
var products = new[]
{
new Product("Apple", "Fruit"),
new Product("Pear", "Fruit"),
new Product("Carrot", "Vegetable")
};
Group them:
var groups = products.GroupBy(p => p.Category);
Iterate:
foreach (var group in groups)
{
Console.WriteLine(group.Key);
foreach (var item in group)
Console.WriteLine(" " + item.Name);
}
Output:
Fruit
Apple
Pear
Vegetable
Carrot
π₯ Joins in LINQ
Joining two lists is common when working with database-like data.
Example:
var result =
from o in orders
join c in customers
on o.CustomerId equals c.Id
select new { c.Name, o.OrderDate };
Method syntax:
var result = orders.Join(customers,
o => o.CustomerId,
c => c.Id,
(o, c) => new { c.Name, o.OrderDate });
π₯ Deferred Execution Explained
LINQ queries do not run immediately.
This does NOT run yet:
var adults = people.Where(p => p.Age >= 18);
This runs:
foreach (var a in adults) Console.WriteLine(a.Name);
Benefits:
- Efficient
- Only processes what you enumerate
- Works like a pipeline
π₯ Converting the Results (ToList, ToArray, ToDictionary)
LINQ returns an IEnumerable<T> by default β not a list.
Use:
ToList()
var list = people.Where(p => p.Age >= 18).ToList();
ToArray()
var array = nums.Take(5).ToArray();
ToDictionary()
var dict = people.ToDictionary(p => p.Name);
π₯ LINQ Best Practices for Beginners
β Use method syntax for most things
Clearer, shorter.
β Avoid Single() unless you mean βthere must be exactly oneβ
Beginners often misuse it.
β Prefer Any() over Count() > 0
Any() is faster.
β Use Select() only when needed
Avoid unnecessary projections.
β Watch deferred execution
If the underlying collection changes, your results change too.
π₯ Full Beginner Projects Using LINQ
Here are three mini-projects perfect for beginners.
Project 1: Create a Search Engine for a List
string search = "ja";
var results = people
.Where(p => p.Name.StartsWith(search, StringComparison.OrdinalIgnoreCase))
.OrderBy(p => p.Name)
.ToList();
Project 2: Calculate Statistics
var average = people.Average(p => p.Age);
var oldest = people.MaxBy(p => p.Age);
var youngest = people.MinBy(p => p.Age);
Project 3: Convert Objects to CSV
var lines = people.Select(p => $"{p.Name},{p.Age}");
string csv = string.Join(Environment.NewLine, lines);
Final Thoughts
LINQ is one of the most powerful features in modern C# programming.
It helps you:
- write cleaner code
- avoid loops
- query data elegantly
- build pipelines
- transform collections
- write production-quality apps faster