How can I confirm if an async EF6 await db.SaveChangesAsync worked as expected?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In EF6, await db.SaveChangesAsync() is considered successful if the awaited task completes without throwing an exception. If you want to confirm that it worked as expected rather than merely "did not crash," you should inspect the returned row count, handle expected exceptions, and, when correctness matters, verify the persisted state with a fresh read.
Start with the Return Value and Exceptions
SaveChangesAsync returns an integer representing the number of state entries written to the database. A basic pattern looks like this:
If the task throws, the save did not complete successfully. Common exceptions include:
- '
DbUpdateException' - '
DbEntityValidationException' - '
DbUpdateConcurrencyException'
So the first confirmation rule is simple:
- no exception means EF believes the save succeeded
- the returned count tells you how many tracked entries were written
That is often enough for straightforward application code.
Know What the Returned Count Does and Does Not Mean
The returned integer is useful, but it is not a perfect business confirmation.
For example:
- a value greater than zero means EF wrote tracked changes
- a value of zero may mean nothing actually changed
- the count reflects EF state entries, not necessarily rows in the exact way you imagine
So if your real question is "did my entity update the way I expected," the return value is only part of the answer.
A stronger verification pattern is to re-read the entity from a new context:
Using a fresh context matters because it forces the verification step to read from the database instead of reusing EF’s in-memory tracked state.
Use Logging and Transactions for Higher Confidence
If correctness is important, logging the save path and wrapping related operations in a transaction makes it easier to prove what happened.
Transactions do not confirm success by themselves, but they make the unit of work explicit. If a later step fails, you can roll the whole operation back instead of guessing which database changes were partially persisted.
In tests, an integration test is usually the best confirmation:
That verifies the database state rather than only the method call.
Do Not Confuse "Awaited" with "Verified"
Because the code is asynchronous, some developers worry that the save may still be "in progress" after await. That is not how await works. Once await db.SaveChangesAsync() returns normally, that save operation has completed from EF’s point of view.
The real uncertainty is usually elsewhere:
- maybe no tracked changes existed
- maybe the wrong entity was modified
- maybe the save succeeded but business expectations were wrong
So the confirmation question is less about async mechanics and more about what level of proof you actually need.
Common Pitfalls
The biggest mistake is assuming that because await returned, the data must have changed exactly as intended. The call may have succeeded while affecting zero entries or while persisting different tracked changes than you expected.
Another issue is verifying with the same DbContext instance. That can give you a false sense of certainty because EF may return tracked entities from memory rather than re-reading from the database.
Developers also sometimes ignore exceptions such as concurrency or validation failures and then wonder why the state is inconsistent. If confirmation matters, exception handling is part of the answer.
Finally, do not overinterpret the returned count. It is useful, but it is not a substitute for checking actual persisted data when the business result matters.
Summary
- '
await db.SaveChangesAsync()is successful if it completes without throwing.' - The returned integer tells you how many tracked entries EF wrote.
- A fresh read from a new
DbContextis the best confirmation of persisted state. - Transactions and logging help when the save is part of a larger unit of work.
- The real question is usually not "did async finish" but "did the database end up in the expected state."

