What are the pros and cons of registering DB context with transient lifetime scopes?
✅ Advantage:
Every injection gets a fresh DbContext, completely isolated.
No risk of cross-request state bleeding.
Can be useful in background tasks (rare cases) when you explicitly want short-lived contexts.
❌ Disadvantages:
Performance cost: Creating a new DbContext repeatedly (sometimes multiple times in the same request) can be expensive.
Multiple DbContexts in one request: If different services use DbContext, each gets its own instance → you may end up with multiple database connections in the same request.
No shared tracking: EF Core tracks entities per DbContext instance. If you fetch an entity in one DbContext and try to update it in another, EF won’t know it’s the same entity (you may hit tracking issues, need Attach).
Can cause transactional inconsistency: If you start a transaction in one DbContext and another DbContext is used in the same request, they won’t share that transaction.
What are the pros and cons of registering DB context with singleton lifetime scopes?
❌ Almost always bad:
A single DbContext is shared by the entire application.
DbContext is not thread-safe → concurrent requests break it.
Entities remain tracked forever → memory leaks and stale data.
Transactions will interfere across requests.
Only useful for very rare special cases (like migrations).
What are the pros and cons of registering DB context with scoped lifetime scopes?
✅ Advantages:
Recommended/default for web apps.
All services within the same request pipeline share one DbContext instance.
Entities tracked consistently → no re-attach issues.
More efficient than transient (fewer DbContext creations).
Supports transactions across multiple services in the same request.
❌ Disadvantage:
If you hold onto the DbContext beyond request scope (e.g., store it in a singleton), you’ll get disposed-object exceptions.
Longer-lived contexts may accumulate too many tracked entities → memory overhead (but manageable if you AsNoTracking() for queries).
When to register DB context with different lifetime scopes?
⭐ Summary
Scoped → ✅ Best for web apps (default).
Transient → ⚠️ Creates new DbContext every time. Safe but inefficient and breaks tracking/transactions.
Singleton → ❌ Dangerous, not thread-safe.
👉 Rule of thumb:
Use Scoped unless you have a very specific reason.
Use Transient only in short-lived background tasks where you explicitly want separate DbContext instances.
Never use Singleton.
What is the difference between an attached and a detached entity in EF Core?
Attached: The entity is tracked by the DbContext. EF Core can detect changes and automatically generate UPDATE statements on SaveChanges().
Detached: The entity exists in memory but is not tracked by any DbContext. EF Core ignores changes to it unless it’s explicitly attached.
What happens if you fetch an entity using one Transient DbContext and try to update it using another Transient DbContext?
The entity becomes detached relative to the second DbContext.
EF Core won’t track changes automatically, so updates don’t persist unless you attach it or set its state explicitly.
How does using a Scoped DbContext solve this problem?
Scoped DbContext ensures that all services within the same request scope share the same DbContext instance.
The entity remains tracked, and EF Core automatically detects changes, so updates persist without manually setting states.
How can you attach a detached entity to a DbContext?
_context.Users.Attach(user);
_context.Entry(user).State = EntityState.Modified;
_context.SaveChanges();
.Attach() starts tracking the entity.
EntityState.Modified marks it for update.
Alternatively:
_context.Users.Update(user); // shortcut for Attach + Modified
How do you handle newly added entities using EntityState?
Use EntityState.Added for new entities:
_context.Entry(newUser).State = EntityState.Added;
_context.SaveChanges(); // generates INSERT
Shortcut: _context.Users.Add(newUser) automatically sets the state to Added.
What does EntityState.Detached do?
Stops tracking the entity in the DbContext.
EF Core ignores any changes to it.
It does not delete or modify the database.
What happens if you set EntityState.Detached on an already untracked entity?
Nothing happens (no-op).
EF Core does not throw an error, but SaveChanges() will still not affect the database.
What is the difference between Attach, Detach, Add, Update, and Remove?
Method Effect on DbContext Tracking DB Action on SaveChanges()
Attach Start tracking, default state Unchanged No DB action unless state changed
Detach Stop tracking None
Add Track as Added INSERT
Update Track as Modified UPDATE
Remove Track as Deleted DELETE
Do Attach and Detach perform any actual database operation?
No, they only affect the DbContext’s change tracker.
Actual database operations happen only on SaveChanges() based on the entity’s state.
Explain how EF Core manages transactions under the hood when multiple DbSets are changed. How would you ensure atomic operations across multiple SaveChanges calls?
By default, each call to SaveChanges or SaveChangesAsync is wrapped in its own transaction.
EF Core tracks changes in the DbContext change tracker.
When you call SaveChanges, EF Core generates SQL commands for all tracked changes and executes them inside a single implicit transaction.
If anything fails (e.g., a constraint violation), EF Core rolls back the transaction, so all operations are reverted.
👉 This guarantees atomicity per SaveChanges call.
By default, EF Core wraps every SaveChanges in its own transaction.
For atomic operations across multiple SaveChanges, use an explicit transaction via BeginTransaction() or TransactionScope.
What is atomicity?
Atomicity (in ACID properties)
Definition: Atomicity means that a transaction is all-or-nothing.
In other words, a transaction’s operations either all succeed together or none of them take effect.
If one operation inside the transaction fails, the database rolls back to the state before the transaction began.