Che differenza fa .AsNoTracking ()?


228

Ho una domanda .AsNoTracking()sull'estensione, dato che è tutto abbastanza nuovo e piuttosto confuso.

Sto usando un contesto per richiesta per un sito Web.

Molte delle mie entità non cambiano, quindi non ho bisogno di essere rintracciate, ma ho il seguente scenario in cui non sono sicuro di cosa accadrà al database o anche se in questo caso fa la differenza.

Questo esempio è quello che sto facendo attualmente:

context.Set<User>().AsNoTracking()
// Step 1) Get user
context.Set<User>()
// Step 2) Update user

È lo stesso di cui sopra, ma rimuovendo .AsNoTracking()dal passaggio 1:

context.Set<User>();
// Step 1) Get user
context.Set<User>()
// Step 2) Update user

I passaggi 1 e 2 utilizzano lo stesso contesto ma si verificano in momenti diversi. Quello che non riesco a capire è se c'è qualche differenza. Dato che il passaggio 2 è un aggiornamento, suppongo che entrambi colpiranno comunque il database due volte.

Qualcuno può dirmi qual è la differenza?

Risposte:


187

La differenza è che nel primo caso l'utente recuperato non viene monitorato dal contesto, quindi quando si desidera salvare l'utente nel database è necessario collegarlo e impostare correttamente lo stato dell'utente in modo che EF sappia che dovrebbe aggiornare l'utente esistente invece di inserirne uno nuovo. Nel secondo caso non è necessario farlo se si carica e si salva l'utente con la stessa istanza di contesto perché il meccanismo di tracciamento lo gestisce per te.


1
Possiamo ottenere gli stessi vantaggi per le classi anonime in query selezionate, come context.Users.Select (u => new {Name = u.Name})? Grazie.
Dilhan Jayathilake,

6
@DilhanJayathilake: le classi anonime non rappresentano l'entità stessa, quindi non hanno tracciamento.
Ladislav Mrnka,

1
Poiché EF6 inserisce la chiave di entità in modo errato in una vista a volte, AsNoTracking () ignora la chiave e quindi rappresenta un'alternativa alla correzione manuale della chiave (presupponendo che non siano necessari altri vantaggi della chiave).
crokusek,

4
Inoltre, l'effetto più grande di AsNoTracking è che il caricamento lento non funzionerà
Douglas Gaskell,

170

vedere questa pagina Entity Framework e AsNoTracking

Cosa fa AsNoTracking

Entity Framework espone una serie di opzioni di ottimizzazione delle prestazioni per aiutarti a ottimizzare le prestazioni delle tue applicazioni. Una di queste opzioni di ottimizzazione è .AsNoTracking(). Questa ottimizzazione consente di dire di Entity Frameworknon tenere traccia dei risultati di una query. Ciò significa che Entity Frameworknon esegue alcuna elaborazione o memorizzazione aggiuntiva delle entità restituite dalla query. Tuttavia, significa anche che non è possibile aggiornare queste entità senza ricollegarle al grafico di monitoraggio.

ci sono significativi miglioramenti delle prestazioni usando AsNoTracking


11
Sembra che i guadagni possano essere controbilanciati a volte: stackoverflow.com/questions/9259480/…
Fabrice,

3
Il mio guadagno in termini di prestazioni con una query complessa durante il caricamento di una relazione figlio principale con inclusione in un passaggio è stato di circa il 50%
Karl

53

Nessuna traccia di query LINQ to Entities

L'uso di AsNoTracking () è consigliato quando la query è destinata alle operazioni di lettura. In questi scenari, si ripristinano le entità ma non vengono monitorate dal proprio contesto, garantendo un utilizzo minimo della memoria e prestazioni ottimali

Professionisti

  1. Prestazioni migliorate rispetto alle normali query LINQ.
  2. Oggetti completamente materializzati.
  3. Più semplice da scrivere con la sintassi integrata nel linguaggio di programmazione.

Contro

  1. Non adatto per operazioni CUD.
  2. Alcune restrizioni tecniche, come ad esempio: I pattern che utilizzano DefaultIfEmpty per le query OUTER JOIN generano query più complesse rispetto alle semplici istruzioni OUTER JOIN in Entity SQL.
  3. Non puoi ancora usare LIKE con la corrispondenza generale del modello.

Maggiori informazioni disponibili qui:

Considerazioni sulle prestazioni per Entity Framework

Entity Framework e NoTracking



10

AsNoTracking () consente di ignorare il requisito "chiave univoca per record" in EF (non menzionato esplicitamente da altre risposte).

Ciò è estremamente utile quando si legge una vista che non supporta una chiave univoca perché forse alcuni campi sono nullable o la natura della vista non è indicizzabile logicamente.

In questi casi la "chiave" può essere impostata su qualsiasi colonna non annullabile, ma AsNoTracking () deve essere utilizzato con tutti i record di query altrimenti (duplicati per chiave) verranno ignorati.


2
Solo per ribadire l'importanza di questo con Views, ho una query da una vista che restituisce 7 record univoci quando viene eseguito tramite SSMS. Quando viene eseguito tramite EF, senza il modificatore AsNoTracking, ottengo il primo record, tre copie della seconda e tre copie della terza. Questo ha richiesto un sacco di incredibili graffi alla testa per essere risolto, e stava usando AsNoTracking che lo ha risolto!
Ade,

Ho avuto lo stesso identico problema durante l'utilizzo di Linq to Entities durante l'interrogazione di una vista senza chiavi primarie. Ho scoperto AsNoTracking solo dopo mezza giornata di graffi alla testa. Questo post sul forum ASP.Net alla fine mi ha portato ad esso. forums.asp.net/t/…
red_dorian

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.