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.
Migrations — dotnet 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)
dotnet ef database update for a production deploy?