Query Syntax
LINQ query syntax provides a readable, SQL-style DSL for querying sequences. It compiles to method chain calls onIEnumerable<T> or IQueryable<T>.
Query Syntax Elements
- from - Selects an iteration variable
- where - Filters elements using any boolean expression
- select - Projects each element to a new shape
- orderby - Supports multiple keys with ascending/descending
- join - Correlates two sequences on a key
- group by - Produces
IGrouping<TKey, TElement>sequences
Method Syntax
LINQ method (fluent) syntax chains extension methods onIEnumerable<T>. More concise for simple operations and integrates smoothly with async LINQ extensions.
Common LINQ Methods
- Filtering
- Projection
- Aggregation
- Where - Filters with predicate
- OfType<T> - Filters and casts by type
- Distinct - Removes duplicates
- Skip/Take - Pagination support
Key Points
- All LINQ methods are lazy by default — execution deferred until enumeration
ToList(),ToArray(),ToDictionary()force immediate evaluationFirst()throws if empty;FirstOrDefault()returns default valueSelectManyflattens nested sequencesAggregateis the general fold operation
Filtering Data
LINQ filtering operators narrow sequences. EF Core translates them to SQL WHERE and LIMIT clauses.Filtering Operators
- Where - Primary filter operator with predicate lambda
- OfType<T> - Filters by type with a cast
- Distinct/DistinctBy - Deduplicates sequences
- TakeWhile/SkipWhile - Operate on ordered sequences
- Intersect/Except/Union - Set-based filters
- Chunk - Splits sequence into fixed-size chunks
Push filters as close to the data source as possible — in EF Core, Where before Select translates to a SQL WHERE, reducing data transfer.
Sorting Data
OrderBy, OrderByDescending, ThenBy, and ThenByDescending compose multi-level sorts.
Sorting Guidelines
OrderBymust precedeThenByin the chain- Multiple
WherebeforeOrderByis fine — only oneOrderByneeded - Use
StringCompareroverloads for case-insensitive sorts - Sorting is stable in LINQ to Objects
- EF Core translates
OrderByto SQL ORDER BY
Grouping Data
GroupBy partitions a sequence into IGrouping<TKey, TElement> collections.
Grouping Concepts
IGrouping<K,V>implementsIEnumerable<V>— iterate it like any sequenceChunk(n)groups consecutive elements (not keyed grouping)ToLookupmaterializes groups into a dictionary-like structure- EF Core translates
GroupByto SQL GROUP BY for supported aggregates GroupJoincorrelates outer and inner sequences like SQL LEFT JOIN
Use ToLookup when you will access groups multiple times — it materializes immediately into an efficient keyed structure.
Joining Data
LINQJoin and GroupJoin correlate two sequences on keys. EF Core translates navigation property includes and explicit joins to SQL JOIN clauses.
Join Types
Inner Join
Join performs an inner join — only matching keys appear in resultsLeft Join
GroupJoin performs a left outer joinJoin Best Practices
Join(inner, outerKey, innerKey, resultSelector)— four argumentsGroupJoinreturns outer with matching inner collection (left join)SelectManyflattensGroupJointo left-join style rows- EF Core
Includeeagerly loads navigation properties ThenIncludehandles nested navigation loading
ADO.NET Fundamentals
ADO.NET provides direct database access via Connection, Command, DataReader, and DataAdapter. It is the foundation beneath all .NET ORMs.ADO.NET Key Concepts
- Always open connections inside
usingblocks DbCommand.Parametersprevents SQL injection — never concatenate SQLDataReaderis forward-only, read-only, fast-streamingCommandType.StoredProcedurecalls database stored proceduresDbTransactionwraps multiple commands in a unit of work- Connection pooling is automatic — avoid unnecessary connection opens
LINQ-to-Objects
LINQ-to-Objects queriesIEnumerable<T> collections in memory. All standard query operators apply to any sequence: arrays, lists, dictionaries, and custom iterables.
Memory Efficiency
yield returnenables lazy generator sequences- PLINQ (
AsParallel()) distributes work across CPU cores ForEachis not standard LINQ —List<T>.ForEachis a List methodRangeandRepeatgenerate numeric/repetition sequencesEnumerable.Empty<T>()is the canonical empty sequence
Use PLINQ (AsParallel()) for CPU-bound transformations over large in-memory collections — easy 4-8x speedup on multi-core machines.
Use yield return
For infinite or expensive-to-generate sequences
Use PLINQ
For embarrassingly parallel data processing
Materialize
With ToList before sharing across threads