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.
fonte
2012-05-07 09:05:41
Grazie. Speravo che avresti notato questo post. Vota il tuo suggerimento anche su Data UserVoice. –
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