LINQ cheat sheet
Filtering, projecting, sorting, grouping, joining and aggregating.
Filtering and projecting
items.Where(x => x.Price < 20) // filter
items.Select(x => x.Name) // transform each element
items.Select((x, index) => $"{index}: {x}") // with index
items.SelectMany(o => o.Lines) // flatten nested collections
items.OfType<Circle>() // filter by type
items.Distinct() items.DistinctBy(x => x.Email)Sorting
items.OrderBy(x => x.Price) items.OrderByDescending(x => x.Price)
items.OrderBy(x => x.Category).ThenBy(x => x.Name)
numbers.Order() numbers.OrderDescending() // sort by the values themselves
items.Reverse()Single elements
| Method | No match | Several matches |
|---|---|---|
First(pred) | throws | first |
FirstOrDefault(pred) | default / null | first |
Single(pred) | throws | throws |
SingleOrDefault(pred) | default | throws |
Last(pred) / LastOrDefault | throws / default | last |
ElementAt(i) | throws if out of range | — |
MaxBy(sel) / MinBy(sel) | default for empty | element with max/min key |
Questions and aggregates
items.Any() items.Any(x => x.Stock == 0) items.All(x => x.Price > 0)
items.Count() items.Count(x => x.IsActive) items.Contains(x)
items.Sum(x => x.Total) items.Average(x => x.Price) items.Min(x => x.Price) items.Max(...)
items.Aggregate((acc, x) => acc * x)Grouping and joining
orders.GroupBy(o => o.Customer)
.Select(g => new { Customer = g.Key, Count = g.Count(), Total = g.Sum(o => o.Total) })
orders.Join(customers, o => o.CustomerId, c => c.Id, (o, c) => new { o.Id, c.Name })
names.Zip(scores, (n, s) => $"{n}: {s}")
items.Chunk(100) // batches of 100
a.Union(b) a.Intersect(b) a.Except(b) a.Concat(b) a.SequenceEqual(b)Paging and conversion
items.Skip(20).Take(10) items.TakeWhile(p) items.SkipWhile(p)
items.ToList() items.ToArray() items.ToHashSet()
items.ToDictionary(x => x.Id) // throws on duplicate keys
items.ToDictionary(x => x.Id, x => x.Name)
items.ToLookup(x => x.Category) // many values per keyQuery syntax
var q = from o in orders
where o.Total > 100
join c in customers on o.CustomerId equals c.Id
orderby o.Total descending
group o by c.City into g
select new { City = g.Key, Count = g.Count() };Deferred vs immediate
| Deferred (returns a query) | Immediate (runs it) |
|---|---|
Where, Select, SelectMany, OrderBy, GroupBy, Join, Skip, Take, Distinct | ToList, ToArray, ToDictionary, Count, Sum, First, Any, Max, foreach |
- Each enumeration re-runs the query →
ToList()once if you'll reuse the results. - With EF Core the same operators become SQL; only translatable expressions work.
Iterators
IEnumerable<int> Evens(int max)
{
for (int i = 0; i <= max; i += 2) yield return i; // lazy, one at a time
}