LINQ Queries
LINQ (Language Integrated Query) in C#
LINQ provides a unified, type-safe query syntax for collections, databases, XML, and more.
Common LINQ extension methods
All operate on IEnumerable<T> and are lazy (evaluated on demand):
Where(predicate)— filters elements.Select(selector)— projects/transforms elements.OrderBy(keySelector)/OrderByDescending— sorts.GroupBy(keySelector)— groups into key-collection pairs.First(predicate)/FirstOrDefault— retrieves first match.Count(predicate)— counts matching elements.Any(predicate)— returns true if any element matches.All(predicate)— returns true if all elements match.
Method vs query syntax
csharp
// Method syntax
var result = data.Where(x => x.Age > 18).Select(x => x.Name);
// Query syntax
var result = from x in data where x.Age > 18 select x.Name;Key points:
- LINQ queries are lazy — they execute when iterated (foreach, ToList, etc.).
ToList()andToArray()force immediate evaluation.- Lambda expressions are the heart of method-syntax LINQ.
Code Examples
Where, Select, OrderBycsharp
using System;
using System.Collections.Generic;
using System.Linq;
class Program {
record Product(string Name, string Category, decimal Price);
static void Main() {
var products = new List<Product> {
new("Apple", "Fruit", 0.5m),
new("Laptop", "Tech", 999m),
new("Banana", "Fruit", 0.3m),
new("Phone", "Tech", 599m),
new("Cherry", "Fruit", 2m),
};
var cheapFruits = products
.Where(p => p.Category == "Fruit" && p.Price < 1)
.OrderBy(p => p.Price)
.Select(p => $"{p.Name}: ${p.Price}");
foreach (var item in cheapFruits)
Console.WriteLine(item);
Console.WriteLine($"Any tech over $800: {products.Any(p => p.Category == "Tech" && p.Price > 800)}");
Console.WriteLine($"All fruits under $5: {products.Where(p => p.Category == "Fruit").All(p => p.Price < 5)}");
}
}LINQ chains are read top-to-bottom: filter, sort, then project. Lazy evaluation means the chain only runs when iterated.
GroupBy and aggregatescsharp
using System;
using System.Collections.Generic;
using System.Linq;
class Program {
record Sale(string Region, decimal Amount);
static void Main() {
var sales = new List<Sale> {
new("North", 100), new("South", 200),
new("North", 150), new("East", 300),
new("South", 250), new("East", 100),
};
var byRegion = sales
.GroupBy(s => s.Region)
.Select(g => new { Region = g.Key, Total = g.Sum(s => s.Amount), Count = g.Count() })
.OrderByDescending(r => r.Total);
foreach (var r in byRegion)
Console.WriteLine($"{r.Region}: ${r.Total} ({r.Count} sales)");
}
}GroupBy partitions elements into groups by key. Projecting each group with Select lets you compute per-group aggregates.
Quick Quiz
1. When does a LINQ query actually execute?
2. What does `Any(predicate)` return if no elements match?
Was this lesson helpful?