Entity Framework non ha una cache di dati per AppDomain, solo una cache per istanza di contesto.
Se si crea un nuovo contesto per richiesta o query, si inizia con una cache vuota e EF recupererà i dati dal database.
Inoltre, il termine "cache per istanza di contesto" può essere fuorviante in quanto non significa che EF non eseguirà query sul database se le entità sono già caricate nella cache di contesto. Il modo in cui questo funziona della cache e come è possibile sfruttare (o no) è la seguente:
Ogni LINQ to Entities query su un DbSet<T>
o in generale su un IQueryable<T>
verrà eseguito una query di database, non importa se le entità esistono già nel contesto o no. Ma se un'entità con la stessa chiave di un'entità interrogata esiste già nel contesto EF getterà via il risultato di quella query e restituirà l'istanza dell'entità memorizzata nella cache al chiamante.
Verifica se l'entità con la stessa chiave esiste dopo ha eseguito la query. (Per le query complesse - ad esempio le query che contengono un Include
-. Non può fare questo controllo prima perché non può sapere quale entità e valori chiave saranno restituiti)
Questo è il comportamento di default (MergeOption
è AppendOnly
). È possibile modificare questo comportamento in OverwriteChanges
e in altre opzioni, credo, ma nessuno di questi eviterà che le query LINQ generino sempre query di database.
Per l'interrogazione di un'entità solo con la sua chiave è possibile utilizzare GetObjectByKey
o Find
(con DbContext
) che controllerà prima se l'entità con quella chiave è già memorizzato nella cache nel contesto e poi restituire questo oggetto in cache. In caso contrario, eseguirà una query di database per caricarlo.
È possibile interrogare ChangeTracker di EF, è particolarmente ben supportato con DbContext
in cui si ha accesso alla cache di contesto tramite la raccolta DbSet<T>.Local
.
Il problema qui è che non esiste una logica per interrogare automaticamente il database se una query su Local
non restituisce un risultato. Devi scrivere questa logica manualmente. Il problema ancora più grande è che una query su Local
è LINQ-to-Objects e non LINQ-to-Entities (Local
non implementa IQueryable<T>
, solo IEnumerable<T>
), quindi è spesso necessario riscrivere le query per agire su Local
- ad esempio non è possibile utilizzare Include
qui, il vostro non è possibile utilizzare alcun EntityFunctions
, si otterrà un comportamento diverso per quanto riguarda i confronti di stringhe maiuscole e minuscole, ecc, ecc
io non la penso così che i dati viene memorizzato nella cache in entità è sempre query DB –