LINQ wraps enumerable data in composable query operators with deferred execution — the query only runs when iterated. IEnumerable<T> executes client-side (LINQ-to-Objects). IQueryable<T> translates the expression tree to SQL in EF Core. .NET 9 adds CountBy (group-count in one pass), AggregateBy (group-aggregate), and Index() (index-value pairs). Query syntax vs method syntax are equivalent; the compiler translates both.
CountBy and AggregateBy: group operations in a single pass.
ctx.Orders.AsEnumerable().Where(...) loads ALL rows into memory first. Always filter while still IQueryable.
.NET 9 CountBy is 30%+ faster for large collections — it counts in a single pass without allocating groups.
Call query.ToQueryString() to inspect the generated SQL in development. Untranslatable expressions silently fall back to client evaluation.
Sign in to share your feedback and join the discussion.