After three hours of debugging and searching, I'm hoping someone here has an answer. Entity Framework (using MySQL) throws the following exception if I call the following function quickly in succession (e.g. < 0.1 seconds apart).
System.InvalidOperationException: Unexpected connection state. When using a wrapping provider ensure that the StateChange event is implemented on the wrapped DbConnection.
However, sometimes the function works without any problems. The exception is thrown on the first ToList()
call:
void InsertOrUpdateMaterials(List<Material> materials)
{
var id = GetUserId();
var materialIds = materials.Select(x => x.MaterialId).ToList();
// Remove old materials from DB
var oldMaterials = Db.Materials.Where(p => p.CreatedBy == id &&
materialIds.Contains(p.MaterialId)).ToList(); // exception
Db.Materials.RemoveRange(oldMaterials);
Db.SaveChanges();
// Replace previous materials with the new ones in list
Db.Materials.AddRange(materials);
Db.SaveChanges();
}
Oddly, this error never occurred on the development server, so I looked into possible configuration issues to no avail.
Sometimes, Entity Framework throws:
System.Data.Entity.Core.EntityCommandExecutionException: There is already an open DataReader associated with this Connection which must be closed first.
Again pointing to the ToList()
call. Any ideas?
Please be careful that you don't use DbContext in other thread, only use it in the UI thread.
If you need to call function that including DbContext from other thread, you need to call it via the
SynchronizationContext
class.I think the DbContext cannot be used at the same time each thread UI and others.
I had this issue with
Effort.EF6
1.3.0. The fix for me was to update theNMemory
dependency from 1.1.0 to 1.1.2.I had the same problem using
Effort.EF6
, but updatingNMemory
(as user326608 suggested) didn't help. Turns out XUnit is executing tests in parallel by default since V2.Disabling this behavior fixed it for me. Add the following to AssemblyInfo.cs:
Although I see this as a workaround, as unit tests should be independent from each other.
For other people that might a similar problem. Based on the above comments it seems that the code uses a cached db-context. After the db-context was created the db-connection broke (no
StateChange
handler was installed in the application). After the connection breakdown the application used the cached db-context to perform some operations on it.Creating a new db-context solved the problem.