跳到主要内容

LINQ — Syntax + Optimization (Master Cheat Sheet)

What is LINQ? (One-liner)

🧠 Memory hook

“LINQ = SQL for objects.”

“LINQ provides a unified way to query in-memory objects, collections, and databases using C# syntax.”


Two LINQ Syntax Styles (Know BOTH)

① Method Syntax (MOST USED)

var result = users.Where((u) => u.Age > 18).Select((u) => u.Name);

② Query Syntax (SQL-like)

var result =
from u in users
where u.Age > 18
select u.Name;

🧠 Rule

Query syntax is compiled into method syntax internally.

“Method syntax is more powerful and commonly used in real projects.”


Core LINQ Categories (Big Picture)

Filtering
Projection
Sorting
Grouping
Aggregation
Quantifiers
Set Operations
Joins
Element Operators
Partitioning

Filtering

Where

.Where(x => x.IsActive)

🧠 Tip

  • Runs lazy
  • Chainable

Projection (VERY IMPORTANT)

Select

.Select(x => x.Name)

Select → DTO (Best Practice)

.Select(x => new UserDto {
Id = x.Id,
Name = x.Name
})

🧠 Optimization rule

Project early → less data → faster queries


Sorting

.OrderBy(x => x.Name)
.ThenBy(x => x.Age)

.OrderByDescending(x => x.CreatedAt)

⚠️ EF Core:

  • Sorting after ToList() = in-memory sort ❌
  • Sorting before ToList() = SQL sort ✅

Grouping

GroupBy

.GroupBy(x => x.Category)

Group + Aggregate

.GroupBy(x => x.Category)
.Select(g => new {
Category = g.Key,
Count = g.Count()
})

🧠 Rule

Grouping is expensive → filter first


Aggregation

.Count()
.Sum(x => x.Price)
.Average(x => x.Score)
.Min()
.Max()

⚠️ EF Core

  • Runs in DB if before ToList()
  • Runs in memory if after

9️⃣ Quantifiers (Return bool)

.Any()
.Any(x => x.IsActive)

.All(x => x.IsActive)

.Contains(value)

🧠 Optimization

Use Any() instead of Count() > 0


Element Operators (Single Item)

.First()
.FirstOrDefault()

.Single()
.SingleOrDefault()

.Last()

🧠 VERY IMPORTANT INTERVIEW RULE

MethodBehavior
FirstAllows many
SingleRequires exactly one
SingleOrDefaultThrows if >1

“Use Single only when uniqueness is guaranteed.”


Partitioning (Pagination)

.Skip(10)
.Take(10)

⚠️ Database warning

Skip on large tables = slow

✅ Better:

.Where(x => x.Id > lastId)
.Take(10)

Set Operations

.Distinct()
.Union()
.Intersect()
.Except()

🧠 Note

  • Distinct() can be expensive
  • Requires equality comparer

Joins (Rare but Important)

Method Syntax Join

.Join(
orders,
u => u.Id,
o => o.UserId,
(u, o) => new { u.Name, o.Total }
)

Query Syntax (Cleaner)

from u in users
join o in orders on u.Id equals o.UserId
select new { u.Name, o.Total }

🧠 EF Core tip

Prefer navigation properties over manual joins.


Deferred vs Immediate Execution ⚠️

Deferred (LAZY)

Where;
Select;
OrderBy;

Immediate

ToList();
ToArray();
First();
Count();

🧠 Rule

Query is NOT executed until enumeration.


LINQ Optimization (REAL WORLD)

❌ Bad

users.ToList().Where((x) => x.IsActive);

✅ Good

users.Where((x) => x.IsActive).ToList();

🧠

Push work to the database


EF Core–Specific Optimizations (YOU USE THIS)

Read-only queries

.AsNoTracking()

Avoid loading everything

.Select(x => new { x.Id, x.Name })

Avoid N+1

.Include(x => x.Orders)

Ignore auto includes

.IgnoreAutoIncludes()

Common LINQ Performance Mistakes ❌

  • ToList() too early
  • Multiple enumerations
  • Select * equivalent
  • Client-side evaluation
  • Large Skip
  • Single() without guarantee

LINQ vs SQL (Interview Gold)

“LINQ is translated to SQL when using EF Core, but not all LINQ can be translated. If translation fails, EF executes in memory, which can cause performance issues.”


9️⃣ 30-Second Interview Answer

“LINQ provides a unified querying syntax for collections and databases. It supports filtering, projection, grouping, and aggregation using deferred execution. For performance, it’s important to push filtering and projection to the database, avoid premature ToList calls, use AsNoTracking for read-only queries, and understand how LINQ translates to SQL in EF Core.”


🧠 Ultra-Short Memorization Block

Where = filter
Select = shape data
OrderBy before ToList
Any > Count
Project early
AsNoTracking for reads
Single only if guaranteed
LINQ is lazy