LINQ
LINQ (Language Integrated Query) is the idiomatic way to query collections, databases, and XML in C#. The pipeline is fluent (.Where().Select()) or query syntax (from x in xs where ...) — pick one.
Filter, project, group, EF Core
EXAMPLE
using System;
using System.Collections.Generic;
using System.Linq;
record User(string Name, int Age, string City, decimal Salary);
var users = new[] {
new User("Ada", 32, "Sydney", 120_000m),
new User("Bo", 28, "Sydney", 95_000m),
new User("Cy", 41, "Melbourne", 140_000m),
new User("Di", 22, "Brisbane", 65_000m),
};
// 1) Filter + project
var names = users
.Where(u => u.Age >= 30)
.OrderByDescending(u => u.Salary)
.Select(u => u.Name)
.ToList();
// 2) Aggregations
decimal totalPay = users.Sum(u => u.Salary);
double avgAge = users.Average(u => u.Age);
int headcount = users.Count();
int count30 = users.Count(u => u.Age >= 30);
// 3) Group
var byCity = users.GroupBy(u => u.City)
.Select(g => new { City = g.Key, Total = g.Sum(u => u.Salary), Count = g.Count() })
.ToList();
foreach (var row in byCity)
Console.WriteLine($"{row.City}: {row.Count} users, payroll {row.Total:C}");
// 4) Join
var orders = new[] { new { UserName = "Ada", Total = 9.99m }, new { UserName = "Ada", Total = 49.99m } };
var joined = users.Join(
orders,
u => u.Name,
o => o.UserName,
(u, o) => new { u.Name, o.Total });
// 5) Distinct, Take, Skip
var uniqueCities = users.Select(u => u.City).Distinct();
var topThree = users.OrderByDescending(u => u.Salary).Take(3);
var pageTwo = users.OrderBy(u => u.Name).Skip(20).Take(20);
// 6) First / Single / Any / All
var first = users.First(u => u.Salary > 100_000); // throws if none
var maybe = users.FirstOrDefault(u => u.Salary > 1_000_000); // null if none
bool hasMin = users.All(u => u.Age >= 18);
bool anyOld = users.Any(u => u.Age >= 65);
// 7) Anonymous projection vs records
var shaped = users.Select(u => new { u.Name, u.City }); // anonymous
// Better in libraries: record DisplayUser(string Name, string City);
// 8) Query syntax — same result, different shape
var q = from u in users
where u.Age >= 30
orderby u.Salary descending
select u.Name;
// 9) LINQ to Entity Framework — translates to SQL
var topByCity = await db.Users
.Where(u => u.Active)
.GroupBy(u => u.City)
.Select(g => new { g.Key, Total = g.Sum(u => u.Salary) })
.OrderByDescending(g => g.Total)
.Take(10)
.ToListAsync();
// 10) Be careful of double-enumeration
var q2 = users.Where(u => u.Age >= 30);
var list = q2.ToList(); // materialise ONCE
foreach (var u in list) Console.WriteLine(u.Name);
int c = list.Count;
// 11) Chunk (5+), Zip, Distinct(comparer)
var batches = Enumerable.Range(1, 23).Chunk(5);
var paired = users.Zip(orders, (u, o) => new { u.Name, o.Total });
Why it matters
LINQ over IEnumerable is in-memory; over IQueryable it translates to SQL. Knowing which side you’re on prevents accidentally pulling a million rows into the app.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
int[] nums = {1, 2, 3, 4, 5};
var evens = nums.Where(n => n % 2 == 0).Sum(); // 6
var names = users.OrderBy(u => u.Name).Select(u => u.Name);
Try it Yourself »
Exercise
Filter elements with LINQ.
var evens = nums.
(n => n % 2 == 0);
PascalCase Where.
Discussion
Loading…