2015-10-20 5 views
8

Nach ein paar Jahren der Verwendung von Entity Framework in unseren Anwendungen ohne Problem hat unser Unternehmen begonnen, Laptops für unsere Benutzer bereitzustellen. Die Laptops werden vor Ort mit einer direkten kabelgebundenen Verbindung zu unserem Netzwerk verwendet.Wie kann ich eine Entity Framework-Verbindung aktualisieren, ohne den Kontext zu entfernen?

Seitdem haben wir einen enormen Anstieg von Abstürzen innerhalb unserer Programme, mit den Protokollen zeigen

Ausnahme gesehen
System.Data.SqlClient.SqlException: A transport-level error has occurred when receiving results from the server. 
(provider: Session Provider, error: 19 - Physical connection is not usable) 

ist meine Theorie, dass das Problem rührt von der Tatsache, dass die Laptops, im Gegensatz zu den PCs, gehen schlafen. Ich denke, dass der Netzwerkadapter deaktiviert wird, wenn der Laptop in den Ruhezustand versetzt wird, und wieder aktiviert wird, wenn es wieder aufwacht. Ich denke, unsere Programme versuchen immer noch, mit dem Server über eine Verbindung zu kommunizieren, die nicht mehr da ist.

So, das war meine Idee zu reagieren:

Microsoft.Win32.SystemEvents.PowerModeChanged 

ich erkennen kann, wenn er aufwacht und die Verbindung zu aktualisieren. Das Problem ist, dass der einzige Weg, wie ich das tun kann, darin besteht, den aktuellen DbContext zu entfernen und einen neuen zu erstellen.

Das Problem dabei ist, dass alle nicht festgeschriebenen Änderungen dann verloren gehen. Wenn der Benutzer den ganzen Tag an der Aktualisierung eines Datensatzes gearbeitet hat, würde er seine Arbeit verlieren. Nicht nur das, aber wir müssten alle unsere Anwendungen und alle unsere Ansichtsmodelle durchgehen und eine Art von Bearbeitungsmodus mit Benachrichtigungen für den Benutzer integrieren. Nicht schön.

Eine zweite Idee, die ich hatte, war eine Methode zum Klonen eines DbContext zu erstellen. Wenn der Computer aufwacht, könnte ich einen neuen DbContext erstellen und den Zustand von dem alten kopieren, bevor ich ihn entsorgere. Aber einige unserer Datenmodelle sind massiv, und eine tiefgreifende Klonmethode für jeden zu erstellen, wäre eine ziemliche Herausforderung.

Es kommt mir vor, dass dies immer noch die Art sein könnte, wie wir gehen müssen ... aber ich wäre blöd, nicht zu überprüfen, ob irgendjemand einen Weg kennt, die Verbindung eines Entity Framework DbContext zu aktualisieren, ohne seine Aktualität zu verlieren Zustand.

Ich würde mich über jeden möglichen Ratschlag freuen, den jemand haben könnte.

+2

nicht sicher, welche Art von Design Sie haben, aber eine große ungesicherte Informationen im Speicher zu halten ist keine gute Idee. Sie sollten die Informationen in regelmäßigen Abständen automatisch speichern. Zumindest wird dadurch die Verlust-Information soweit wie möglich minimiert. Viele Anwendungen (einschließlich Web-Apps) verwenden diese Strategie. –

+0

Das ist ein fairer Punkt. Der Grund, warum wir nicht automatisch speichern, liegt darin, dass wir Benutzern erlauben, zu entscheiden, ob sie Änderungen speichern oder abbrechen möchten. Um dies zu tun, gibt es zwei Strategien: 1) Erstellen einer Kopie der ursprünglichen Daten im Speicher, wenn eine Bearbeitung beginnt, Live-Aktualisierungen der Datenbank während der Änderung der Daten erhalten, beim Abbrechen Aktualisieren der Daten mit der alten Kopie. 2) Bewahren Sie eine Arbeitskopie im Speicher auf und bleiben nur in der Datenbank bestehen, wenn der Benutzer seine Änderungen speichern möchte. Aus einer Implementierungsperspektive ist die zweite Option einfacher und ist die Methode, die wir verwenden. Dies führt jedoch zu Problemen wie dem oben genannten. – Chronicide

+0

Gibt es kein Ereignis, das vor dem Einschlafen des Laptops auftritt? Du könntest vorher speichern, die Verbindung schließen und wenn es aufwacht, öffne es einfach wieder. – Matt

Antwort

0

Ich wollte nur kommentieren, aber ich habe nicht genügend Reputationspunkte, um das zu tun, also habe ich mich gefragt, ob es nicht möglich ist, in einem getrennten Zustand mit Entity Framework zu arbeiten? Vielleicht kann der Artikel in dem unten stehenden Link helfen:

https://msdn.microsoft.com/en-us/data/jj592676.aspx

+0

Danke für die Referenz. Leider löst es nicht das Problem, dass Entity Framework versucht, über eine Verbindung zu kommunizieren. Allerdings ist es ein klarer Artikel darüber, wie man Entitäten an einen Kontext anhängt, was sehr hilfreich sein könnte, wenn ich eine Klonmethode erstellen müsste ... anstatt neue Einträge zu erstellen, könnte ich die vorhandenen Einträge hinzufügen, die als hinzugefügt oder markiert sind modifiziert von meinem alten Kontext. Das würde ein wenig experimentieren, aber es ist immer noch eine sehr gute Ressource. Vielen Dank. – Chronicide

3

Ich bin nicht sicher, ob es in Ihrem speziellen Fall helfen, aber Sie können den Status der von Ihrer DbConetxt-Klasse verwendete Verbindung überprüfen und schließlich öffne es erneut.

if(context.Database.Connection.State == ConnectionState.Closed) { 
    context.Database.Connection.Open(); 
} 

es kann auch eine Verbindung mit den DbContext in seinem Konstruktor übergeben und diese Verbindung manuell verwalten.

var conn = new SqlConnection("{connectionString}")); 
var context = new DbContext(conn, contextOwnsConnection: false); 

... 

if(conn.State == ConnectionState.Closed) { 
    conn.Open(); 
} 
context.SaveChanges(); 

... 

context.Dispose(); 
conn.Dispose(); 

Es gibt einige Einschränkungen, wenn Sie diesen Code in der Version EF 5 oder früher verwenden möchten. Siehe official documentation.

Verwandte Themen