← All topics
🧰 Core Tech Refresher

Entity Framework Core

DbContext lifetime, change tracking, migrations, the N+1 trap.

DbContext lifetime — registered Scoped by default via AddDbContext; it is not thread-safe and is meant to be short-lived (one per unit of work / request), which is exactly why it pairs naturally with the Unit of Work pattern topic below.

Change tracking — EF Core tracks entities loaded via a tracking query so SaveChanges() knows what to update. AsNoTracking() skips this for read-only queries — cheaper, and the correct default for query-side (CQRS "Q") operations where you're never going to call SaveChanges on that result.

The N+1 problem — lazy-loading (or looping and querying per item) issues one query per row instead of one query total. Fix with eager loading (Include/ThenInclude), projection (Select into a DTO, which also avoids over-fetching columns), or explicit batching.

Migrationsdotnet ef migrations add X generates a diff against the model snapshot; dotnet ef database update applies it. Know that migrations are just C# code you can hand-edit, and that in a real pipeline you'd generate a SQL script (dotnet ef migrations script) for review/CI rather than running database update directly against production.

Flashcards (4)

Why is DbContext registered as Scoped, not Singleton, by default?
tap to reveal answer
It isn't thread-safe and is meant to represent one unit of work with a bounded lifetime (typically one HTTP request) — sharing it across requests/threads causes state corruption and concurrency exceptions.
What does AsNoTracking() do and when should you always use it?
tap to reveal answer
Skips EF Core's change-tracking bookkeeping for the returned entities — cheaper and correct for any read-only query where you won't call SaveChanges on those instances (i.e. most query/CQRS-read-side code).
What is the N+1 query problem and name two fixes.
tap to reveal answer
Issuing 1 query to get a list, then N more queries (one per item) to get related data — usually from lazy loading in a loop. Fix with eager loading (Include/ThenInclude) or projecting directly into a DTO with Select.
What's the safer alternative to dotnet ef database update for a production deploy?
tap to reveal answer
dotnet ef migrations script to generate a reviewable SQL script, run through the normal DB change process/CI — avoids EF's migration runner needing prod DB credentials and lets a DBA review the actual SQL.