14

Questo è il mio primo progetto EF quindi portatemi per favore.Multipleactivereultset in Entity Framework 4.1 Codice First

Quando si aggiorna un'entità come Reparto, si estrae dal contesto, si aggiornano i suoi valori e si chiama context.SaveChanges. Tuttavia, se si aggiorna Department.Employees, EF non lo trova divertente.

Ho cercato e si avvicinò con la possibilità di impostare MultipleActiveResultSets = true nella stringa di connessione, ma voglio sapere se:

  • È questo il modo consigliato?
  • influisce negativamente sulle prestazioni/che cosa devo cercare?

risposta

33

Abilitare MARS è necessario solo se si desidera eseguire più query sulla stessa connessione in parallelo. Questo succede se fai qualcosa del genere:

/* Foreach uses an iterator over the resultset of your query, but the query is not fetched 
    immediately, instead the iterator internally triggers fetching for single 
    processed record from opened data reader. Because of that the query and the reader 
    are active until the iteration is over. */ 
foreach (var department in context.Departments.Where(...)) 
{ 
    /* The first query is still active on the connection but now you are executing 
     lazy loading of all related employees =>. You are executing a second query and, 
     without MARS, you will get an exception. */ 
    var employee = department.Employees.FirstOrDefault(...); 
} 

Come evitare quello?

  • Usa eager loading invece di caricamento pigro: context.Departments.Include(d => d.Employees)
  • Materialize risultato intero reparto impostato prima di utilizzare lazy loading. Significa non accedere ai dipendenti all'interno del ciclo.
  • Abilita MARS e l'esempio citato si limiterà a lavorare

È questo il modo consigliato? Influisce negativamente sulle prestazioni/ a cosa devo prestare attenzione?

Dipende dal problema che si sta tentando di risolvere. Se si dispone di più reparti da elaborare, l'accesso alla propria collezione di dipendenti attiverà una query separata per ciascun reparto. Questo è chiamato N + 1 problema: hai N reparti e una query per recuperarli e per ogni dipartimento eseguirai una query aggiuntiva => N + 1 query. Per un numero enorme di reparti questo sarà un killer delle prestazioni.

Il caricamento di Eager non è una soluzione a prova di proiettile. Può affect performance as well. A volte è sufficiente eseguire query separate per recuperare tutti i reparti necessari e separare le query per recuperare tutti i dipendenti necessari. Se il caricamento è pigro disattivato, è necessario correggere le relazioni e compilare correttamente la proprietà Dipendenti. A proposito, ho fatto un suggestion on Data UserVoice per supportare questa funzionalità fuori dalla scatola.

+0

Grazie. Speravo che avresti notato questo post. Vota il tuo suggerimento anche su Data UserVoice. –

+0

Per riferimento futuro sappiate anche che ** in parallelo è solo a livello di codice **. Dalla documentazione MSDN * MARS abilita l'esecuzione intercalata di più richieste all'interno di una singola connessione. Cioè, consente l'esecuzione di un batch e, nell'esecuzione, consente l'esecuzione di altre richieste. Si noti, tuttavia, che MARS è definito in termini di interleaving, non in termini di esecuzione parallela. * Https://msdn.microsoft.com/en-us/library/ms131686.aspx – PedroC88

Problemi correlati