पाठ 14 / 25
LINQ
Query in-memory data with LINQ and understand deferred execution.
Queries as composable methods
LINQ (Language Integrated Query) adds query operators to any IEnumerable<T>: Where (filter), Select (project), OrderBy/ThenBy, GroupBy, Join, Any/All, Count, Sum, First/FirstOrDefault, Distinct, Take/Skip, Chunk and many more. You can write the same query in method syntax (orders.Where(o => o.Total > 500)) or query syntax (from o in orders where o.Total > 500 select o). Most operators use deferred execution: building the query does nothing; it runs when you enumerate it (with foreach, ToList(), Count() and so on), and it runs again each time you enumerate. Call ToList() or ToArray() when you want a snapshot. LINQ to Objects works on in-memory data with delegates; IQueryable<T> providers, such as Entity Framework Core, translate the same operators into SQL.
Grouping and summarising orders
Nothing executes until ToList() is called.
var orders = new List<Order>
{
new("o1", "Pune", 1200m), new("o2", "Delhi", 300m),
new("o3", "Pune", 800m), new("o4", "Delhi", 2500m),
};
var byCity = orders
.Where(o => o.Total >= 500m)
.GroupBy(o => o.City)
.Select(g => new { City = g.Key, Count = g.Count(), Revenue = g.Sum(o => o.Total) })
.OrderByDescending(x => x.Revenue)
.ToList(); // executes here
foreach (var row in byCity)
Console.WriteLine($"{row.City}: {row.Count} orders, {row.Revenue:C}");
bool anyBig = orders.Any(o => o.Total > 2000m);
record Order(string Id, string City, decimal Total);First versus FirstOrDefault versus Single
First throws if nothing matches; FirstOrDefault returns null/default; Single throws if there is not exactly one match. Choose deliberately: Single documents that duplicates would be a bug.
त्वरित जाँच: When does a LINQ query like `orders.Where(o => o.Total > 500)` actually run?
- When the line is executed
- At compile time
- Only when the garbage collector runs
- When it is enumerated, for example by foreach or ToList()
Answer
When it is enumerated, for example by foreach or ToList() — Most LINQ operators are deferred and execute on enumeration.