Skip to main content

LINQ Cheatsheet

C# 16 views Apr 2026

Filtering

// Where — filter elements
var adults = people.Where(p => p.Age >= 18);

// OfType — filter by type
var strings = objects.OfType<string>();

// Distinct / DistinctBy
var unique = nums.Distinct();
var uniquePeople = people.DistinctBy(p => p.Email);  // .NET 6+

Projection

// Select — transform elements
var names = people.Select(p => p.Name);
var dtos  = people.Select(p => new { p.Id, p.Name });  // anonymous type

// Select with index
var indexed = items.Select((item, i) => new { Index = i, Item = item });

// SelectMany — flatten nested collections
var allTags = posts.SelectMany(p => p.Tags);
var pairs   = list1.SelectMany(a => list2, (a, b) => (a, b));

Ordering

var sorted   = people.OrderBy(p => p.LastName)
                     .ThenBy(p => p.FirstName);

var reversed = people.OrderByDescending(p => p.Age)
                     .ThenByDescending(p => p.Name);

var shuffled = items.OrderBy(_ => Guid.NewGuid());  // random order

Grouping

// GroupBy — returns IGrouping<TKey, TElement>
var byDept = employees.GroupBy(e => e.Department);
foreach (var g in byDept) {
    Console.WriteLine($"{g.Key}: {g.Count()} employees");
}

// Project the groups
var summary = employees
    .GroupBy(e => e.Department)
    .Select(g => new {
        Dept    = g.Key,
        Count   = g.Count(),
        AvgSal  = g.Average(e => e.Salary),
        TopEarn = g.Max(e => e.Salary)
    });

// ToLookup — like GroupBy but eagerly evaluated (good for repeated access)
var lookup = employees.ToLookup(e => e.Department);
var devs   = lookup["Engineering"];

Joining

// Join — inner join
var result = orders.Join(
    customers,
    o => o.CustomerId,
    c => c.Id,
    (o, c) => new { o.Id, c.Name, o.Total }
);

// GroupJoin — left outer join
var withOrders = customers.GroupJoin(
    orders,
    c => c.Id,
    o => o.CustomerId,
    (c, ords) => new { c.Name, Orders = ords.ToList() }
);

// Zip — pair two sequences
var pairs = names.Zip(scores, (name, score) => $"{name}: {score}");

Aggregation

nums.Count();
nums.Count(x => x > 5);   // conditional count
nums.Sum();
nums.Sum(x => x * 2);
nums.Min(); nums.Max();
nums.Average();
nums.Aggregate((acc, x) => acc + x);             // custom fold
nums.Aggregate(0, (acc, x) => acc + x);          // with seed

// MinBy / MaxBy (.NET 6+)
var youngest = people.MinBy(p => p.Age);
var richest  = people.MaxBy(p => p.Salary);

Partitioning

// Pagination
var page = items.Skip(20).Take(10);

// Chunk (.NET 6+) — split into batches
foreach (var batch in items.Chunk(100)) {
    ProcessBatch(batch);
}

// TakeWhile / SkipWhile
var head = nums.TakeWhile(x => x < 10);
var tail = nums.SkipWhile(x => x < 10);

Element Operations

nums.First();                     // throws if empty
nums.First(x => x > 5);
nums.FirstOrDefault();            // returns default if empty
nums.FirstOrDefault(x => x > 5, -1);  // .NET 6+ with fallback

nums.Single();                    // throws if not exactly one
nums.SingleOrDefault();

nums.Last(); nums.LastOrDefault();
nums.ElementAt(3);
nums.ElementAtOrDefault(100);

Set Operations

a.Union(b);                  // a ∪ b (distinct)
a.Intersect(b);              // a ∩ b
a.Except(b);                 // a − b
a.Concat(b);                 // a + b (with duplicates)

// By key (.NET 6+)
a.UnionBy(b, x => x.Id);
a.IntersectBy(b.Select(x => x.Id), x => x.Id);
a.ExceptBy(b.Select(x => x.Id), x => x.Id);

Quantifiers

nums.Any();                   // has any element?
nums.Any(x => x > 100);      // any match predicate?
nums.All(x => x > 0);        // all match predicate?
nums.Contains(5);             // contains value?
nums.SequenceEqual(other);    // same elements in order?

Conversion

nums.ToList();
nums.ToArray();
nums.ToHashSet();
nums.ToDictionary(x => x.Id, x => x.Name);
nums.AsEnumerable();          // force IEnumerable (stop EF translation)
nums.AsQueryable();

Query Syntax vs Method Syntax

// Query syntax (SQL-like)
var result =
    from p in people
    where p.Age >= 18
    orderby p.Name
    select new { p.Name, p.Age };

// Method syntax (equivalent)
var result = people
    .Where(p => p.Age >= 18)
    .OrderBy(p => p.Name)
    .Select(p => new { p.Name, p.Age });

// Mixed — join is easier in query syntax
var result =
    from o in orders
    join c in customers on o.CustomerId equals c.Id
    where o.Total > 100
    select new { c.Name, o.Total };

Found this helpful? Share it!

Tweet LinkedIn WhatsApp
Translate Page