2015-10-20 15 views
8

Dopo alcuni anni di utilizzo di Entity Framework nelle nostre applicazioni senza problemi, la nostra azienda ha iniziato a distribuire laptop ai nostri utenti. I laptop vengono utilizzati sul posto, con una connessione diretta e cablata alla nostra rete.Come aggiornare una connessione Entity Framework senza eliminare il contesto

Da allora, abbiamo visto un enorme aumento di incidenti all'interno dei nostri programmi, con i registri di eccezione che mostra

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) 

La mia teoria è che il problema deriva dal fatto che i computer portatili, a differenza dei PC, vanno dormire. Penso che l'adattatore di rete sia disabilitato quando il portatile va in stop e riabilitato quando riattiva il backup. Penso che i nostri programmi stiano ancora provando a comunicare con il server usando una connessione che non c'è più.

Quindi, la mia idea era quella di rispondere a:

Microsoft.Win32.SystemEvents.PowerModeChanged 

posso rilevare quando si sveglia e aggiornare la connessione. Il problema è che l'unico modo in cui posso sembrare di farlo è quello di eliminare l'attuale DbContext e istanziarne uno nuovo.

Il problema con questo è che tutte le modifiche senza commit vengono quindi perse. Se l'utente ha lavorato tutto il giorno all'aggiornamento di un record, perderebbe il lavoro. Non solo, ma dovremmo passare attraverso tutte le nostre applicazioni e tutti i nostri viewmodels e incorporare una sorta di kick out della modalità di modifica con le notifiche all'utente. Non è affatto carino.

Una seconda idea che ho avuto è stata quella di creare un metodo per clonare un DbContext. Quando il computer si risveglia, potrei creare un nuovo DbContext e copiare lo stato da quello precedente prima di eliminarlo ... ma alcuni dei nostri modelli di dati sono enormi e creare un metodo di clonazione profondo per ciascuno sarebbe piuttosto un'impresa.

Mi sembra che questo potrebbe ancora essere il modo in cui dobbiamo andare ... ma sarei stupido a non controllare se qualcuno sa di un modo per aggiornare la connessione di un Entity Framework DbContext senza perdere il suo attuale stato.

Gradirei qualsiasi consiglio che qualcuno possa avere.

+2

non si sa quale tipo di progetto si dispone, ma mantenendo una grande informazioni non salvate in memoria non è una buona idea. Dovresti in qualche modo salvare periodicamente le informazioni. Almeno con quello le informazioni di perdita se c'è ne sarà minimizzato il più possibile. Molte applicazioni (comprese le app Web) utilizzano questa strategia. –

+0

Questo è un punto giusto. Il motivo per cui non salviamo automaticamente è perché consentiamo agli utenti di decidere se salvare le modifiche o annullare. Per fare ciò, ci sono due strategie: 1) creare una copia dei dati originali in memoria quando inizia una modifica, mantenere gli aggiornamenti in tempo reale al database man mano che i dati vengono modificati, su Annulla aggiornare i dati con la vecchia copia. 2) Mantieni una copia funzionante in memoria, e resisti al database solo quando l'utente sceglie di salvare le sue modifiche. Dal punto di vista dell'implementazione, la seconda opzione è più semplice ed è il metodo che usiamo. Detto questo, porta a problemi come quello visto sopra. – Chronicide

+0

Non c'è un evento disponibile che si verifica prima che il laptop vada in stop? È possibile salvare in anticipo, chiudere la connessione e quando si riattiva, basta riaprirla. – Matt

risposta

0

Stavo andando a commentare ma non ho abbastanza punti reputazione per farlo, quindi comunque mi chiedevo se non è possibile lavorare in uno stato disconnesso con Entity Framework? Forse l'articolo sul link qui sotto può aiutare:

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

+0

Grazie per il riferimento. Sfortunatamente, non risolve il problema di Entity Framework che tenta di comunicare usando una connessione morta. Detto questo, è un chiaro articolo su come allegare entità a un contesto, che potrebbe essere molto utile se dovessi creare un metodo clone ... piuttosto che creare nuove voci, potrei allegare le voci esistenti che sono contrassegnate come aggiunte o modificato dal mio vecchio contesto. Ciò richiederebbe un po 'di sperimentazione, ma è comunque un'ottima risorsa. Grazie. – Chronicide

3

non sono sicuro, se sarà aiuterà nel vostro caso specifico, ma è possibile controllare lo stato della connessione utilizzata dalla classe DbConetxt e, infine, riaprilo.

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

è anche possibile passare una connessione al DbContext in esso è costruttore e gestire questa connessione manualmente.

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

Ci sono alcune limitazioni, se si desidera utilizzare questo codice in EF 5 o versioni precedenti. Vedere official documentation.

Problemi correlati