2015-02-22 5 views
16

Nach drei Stunden Debuggen und Suchen hoffe ich, dass jemand hier eine Antwort hat. Entity Framework (unter Verwendung von MySQL) löst die folgende Ausnahme aus, wenn ich die folgende Funktion schnell nacheinander aufrufe (z. B. < mit 0,1 Sekunden Abstand).Entity Framework "Unerwarteter Verbindungsstatus" Exception

System.InvalidOperationException: Unerwarteter Verbindungsstatus. Stellen Sie bei Verwendung eines Wrapping-Providers sicher, dass das StateChange-Ereignis in der umschlossenen DbConnection implementiert ist.

Manchmal funktioniert die Funktion jedoch ohne Probleme. Die Ausnahme wird auf dem ersten ToList() Aufruf geworfen:

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(); 
} 

Merkwürdig ist, dass dieser Fehler nie auf dem Entwicklungsserver aufgetreten ist, so sah ich in mögliche Konfigurationsprobleme ohne Erfolg.

Manchmal Entity Framework wirft:

System.Data.Entity.Core.EntityCommandExecutionException: Es gibt bereits eine offene Datareader dieser Verbindung zugeordnet, die zuerst geschlossen werden muss.

Nochmals auf den ToList() Aufruf verweisen. Irgendwelche Ideen?

+4

Es wäre hilfreich zu sehen, woher 'Db' kommt. Meine Vermutung ist, dass es wirklich die Wahrheit sagt - zwischen dem Öffnen der ersten Verbindung auf Db und dem Ausführen von 'ToList' (Sie erhalten hier die Ausnahme, da die Abfrage" materialisiert "wird) den Zustand der Verbindung hat sich geändert (geschlossen usw.). EF weist darauf hin, dass Sie 'StateChange' handhaben sollten, um das zu handhaben (z. B. wieder geöffnete Verbindung oder was auch immer) –

+6

Ihr Kommentar hat mir geholfen, die Lösung zu finden! Danke mein Herr!! Ich schaute, wo 'Db' herkam, und der Kontext wurde zwischengespeichert. Ich habe jedes Mal einen neuen Kontext initialisiert und das Problem gelöst. Wirklich überraschend, wie ich den einen rutschen lasse. – arao6

+3

@ arao6, um eine detailliertere Antwort zu schreiben? Zu Ihrer Information: Sie können in StackOverflow eine Antwort auf Ihre eigene Frage schreiben. Und, FWIW, werde ich wahrscheinlich upvote :) – knocte

Antwort

4

Für andere Leute, die ein ähnliches Problem haben könnten. Aufgrund der obigen Kommentare scheint der Code einen zwischengespeicherten DB-Kontext zu verwenden. Nachdem der db-context erstellt wurde, ist die db-connection abgebrochen (kein StateChange Handler wurde in der Anwendung installiert). Nach dem Zusammenbruch der Verbindung verwendete die Anwendung den zwischengespeicherten db-Kontext, um einige Operationen darauf auszuführen.

Das Erstellen eines neuen DB-Kontextes löste das Problem.

0

Ich hatte dieses Problem mit Effort.EF6 1.3.0. Der Fix für mich war, die NMemory Abhängigkeit von 1.1.0 zu 1.1.2 zu aktualisieren.

+0

Ich bekomme immer noch den Fehler mit NMemory 1.1.2. – Roger

+0

sehen Sie das gleiche Problem Parallelisierung als https://stackoverflow.com/a/47862865? – user326608

+1

Ich bin mir nicht sicher, ich benutze NUnit 3.7. Ich habe mein Problem behoben, indem ich die Art und Weise änderte, wie mein DbContext behandelt wurde, wie Stephen Byrne vorgeschlagen hatte. – Roger

0

Ich hatte das gleiche Problem mit Effort.EF6, aber die Aktualisierung NMemory (wie user326608 vorgeschlagen) hat nicht geholfen. Stellt sich XUnit is executing tests in parallel by default since V2 heraus.

Deaktivieren dieses Verhalten hat es für mich behoben. Fügen Sie die folgende zu AssemblyInfo.cs:

using Xunit; 
[assembly: CollectionBehavior(CollectionBehavior.CollectionPerAssembly)] 

Obwohl ich dies als eine Abhilfe zu sehen, wie Unit-Tests sollten voneinander unabhängig sein.