How to reset entity framework data context after error - entity-framework

We have a huge codebase using EF and occasionally an error occurs which keeps any additional EF commands from executing. Our code uses DI so the services should be getting their own instance of the data context. But it seems like somewhere something is going on where if an error occurs on the context, then any further EF calls will fail and will just throw the original error message. So it appears that if it fails on an insert, update, or delete, then the next EF call that is made from another place will try to first execute the failing command again and it just continues to error until we stop and restart the application.
So, is there a way in our error handler code that intercepts all exceptions in the application to get any instance of the data context and reset it so that it doesn't continue to error on any later calls to it?

Related

Entity Framework - Will SaveChanges behave correctly if called again after an exception?

If you call SaveChanges and it throws an exception (say, because of a concurrency exception), and then you call it a 2nd time, will SaveChanges try to "replay" the same database commands, or will it just "pick up where it left off" or will it just be all messed up and you shouldn't call it again?
And what if it was in an explicit transaction when it threw, and you exited that transaction and then entered an new one and called SaveChanges again?
I'm not talking about EF Core, but you can give me the answer for that as well.

Using ExecuteSqlCommand and SavesChanges within same transaction with EntityFramework Core

I am chasing an issue with MySql / EF Core where I randomly have an exception thrown saying Nested transactions are not supported. This exception does not occur when my system is only used by one user. But when I run my tests in parallel or when I have multiple users, the exception occurs. I looked at all the code and their is nothing that could create nested transactions.
The only piece of codes that scares me so far is something like the following:
using (var transaction = _context.Database.BeginTransaction())
{
// Create a few entities and add them to the EF context
...
// Insert the rows: hopefully at this point, my transaction is not commited yet.
_context.SaveChanges();
// I then want to update a few rows with a raw sql statement without
// having to load the entities in memory.
_context.Database.ExecuteSqlCommand("UPDATE ...");
// Now that I have inserted and inserted some data, I want to commit all these
// changes atomically.
transaction.Commit();
}
Is this safe? Am I guaranteed that my SaveChanges and ExecuteSqlCommand will be executed on the same MySqlConnection? I have the feeling that when I call SaveChanges, it closes my connection and puts it back on the connection pool. Then, my ExecuteSqlCommand takes a new connection from the pool (it may be the same one or another one). So my initial connection (the one where I opened the transaction) is put back in the pool and it could be reused by another thread.
This is just a hunch and I am totally not sure if this could cause the problem.
My real question in the end is:
is it safe to use SaveChanges and ExecuteSqlCommand within a transaction?
I upgraded from MySql.Data.EntityFrameworkCore/MySql.Data 6.10.1-beta to 6.10.3-rc and it looks like the problem is gone. Since the problem was random I can't be totally sure that the problem is indeed fixed, but so far so good.
EDIT:
3 years later, the problem was never observed anymore.

EntityFramework Insert fails due to Trigger and OptimisticConcurrencyException is thrown, how to handle it?

I have a trigger in DB that forbids inserting duplicated data. When I enter duplicated data, it adds nothing to the table, OptimisticConcurrencyException is thrown and I am swallowing (ignoring) this exception. When I try to enter new correct object, EF tries to run both INSERTs and it fails again on the first one.
How can I recover from this, all examples are discussing failed UPDATES, is there anything about INSERT? As I have read creating new DatabaseContext will solve the problem, but I cannot do it that way.
Creating a new DatabaseContext is always the best choice (since Hibernate).
In your case you need to remove the entity that caused the error from the context.
((IObjectContextAdapter)context).ObjectContext.Detach(entity);
You can ask ObjectContext to ignore all the changes after the ignorable exception is thrown. This way the added entity is marked Unchanged; hence in the next SaveChanges call, context won't consider it to manipulate DB:
(yourContextObject as IObjectContextAdapter).AcceptAllChanges();

Entity Framework 5 - "Conflicting Changes Detected"

In our EF 5 application, when we get a SQL Server deadlock error on an insert or update, we immediately try the operation again. However, when we attempt to do so, we're getting the following error:
"Conflicting changes detected. This may happen when trying to insert multiple entities with the same key."
This error is not coming from SQL Server. This is an EF 5 error. And we are not attempting to insert multiple entities with the same key. IOW, we're not attempting to insert a duplicate row. However, I suspect this error means something else. But I'm not entirely certain I know what the issue is. If I had to guess, I would say that on the first attempt, EF sees where trying to insert an entity. It fails because of a deadlock. When we immediately try again, EF thinks we're trying to do the very same operation again, with the same key, and doesn't like it. Not sure how to get around this.
It sounds like you might be trying to execute your queries against the same instance of the DbContext. In which case, your changes are already pending from the last try.
Since there is no “undo pending changes” on the context, you must dispose and recreate the context in between “retries”.

logs from entity framework generation

I'm using EF to communicate with my database.
I made a function import mapping so I can call a Stored Procedure. By on run time I get a error saying "Method not found" referring the method that was created to invoke the SP.
I'm assuming that is an error during the generation on run time.
The question is: Is there any way to see what's going on during the execution time generation so I can find the problem?