2010-08-25 17 views
8

Ho messo insieme un piccolo sito ASP.NET MVC 2 che esegue alcune estese data mining/tabelle-join/ecc.SQL Caching ed Entity Framework

Utilizzando MVC, ho un controller che restituisce i dati in molte forme diverse (tabelle, immagini, ecc.). Per salvare colpire il database spesso ho un duplice meccanismo di cache:

  1. Per i parametri identici alla stessa azione io uso la OutputCacheAttribute con VaryByParam = "*".
  2. Supponendo che alcuni parametri dell'azione siano cambiati (o venga chiamata un'altra azione), è ancora possibile che i miei "dati" siano stati precedentemente richiesti, quindi memorizzo i dati in un modello di vista dopo il primo hit del database, Lo raggiungo con .NET 4.0 System.Runtime.Caching.ObjectCache.

Esempio di ObjectCache interno del regolatore:

private static readonly ObjectCache cache = 
     new MemoryCache("CompareControllerCache"); 
private static void CacheObject(ViewModel obj, 
           string param1, 
           int someOtherParam) 
{ 
    string key = string.Format("{0}-{1}", param1, someOtherParam); 
    Trace.WriteLine(string.Format("Adding {0} to the cache", key)); 
    cache.Add(key, obj, new CacheItemPolicy 
     { 
      SlidingExpiration = TimeSpan.FromMinutes(1) 
     }); 
} 

// Corresponding GetCachedObject with similar key defining logic. 

Questo mi dà un buon miglioramento delle prestazioni, ma dove non riesce è sul CacheItemPolicy essere molto semplice. Idealmente, mi piacerebbe che la finestra della cache fosse più grande, ma l'elemento memorizzato nella cache scade se il database cambia.

La CacheItemPolicy sembra sostenere questo con la collezione ChangeMonitors, alla quale ho potuto aggiungere un SqlChangeMonitor, ma quando si cerca di costruire questo è dove io vengo a una battuta d'arresto.

Sto utilizzando Entity Framework 4 per accedere a un database SQL, come come si costruisce lo SqlChangeMonitor per monitorare le coppie di tabelle del database che possono attivare una scadenza della cache?

SqlChangeMonitor è costruito con un SqlDependency che prende un SqlCommand - come posso fermo su di incapsulamento di Entity Framework del mio database?

+0

Abbastanza buona domanda. Non penso sia possibile ma lascia aspettare e vedere. – jfar

risposta

7

È possibile avvolgere qualsiasi query LINQ arbitraria in una dipendenza Sql, incluse le query EF Linq, vedere LinqToCache. Ma sfortunatamente il modo in cui EF sceglie di formulare l'SQL per le query, anche il più semplice from t in context.table select t, non è compatibile con la restrizione Query Notifica e SqlDependency viene immediatamente invalidata come un'istruzione non valida. Ne ho parlato in SqlDependency based caching of LINQ Queries.

Quello che puoi fare è usare SqlChangeMonitor con gli oggetti semplici SqlCommand costruiti come semplici SELECT ... FROM Table sui tuoi tavoli che probabilmente cambieranno. È necessario comprendere che esiste un equilibrio tra il costo della configurazione delle notifiche e il costo del polling, se le tabelle cambiano di frequente, quindi il monitoraggio delle modifiche potrebbe rivelarsi più costoso del polling. Vedi questo articolo The Mysterious Notification per capire come funziona QN e qual è il costo del monitoraggio.

+0

In questo caso specifico, i dati cambiano molto di rado (10-20 record aggiornati a settimana), ma questo è un progetto di apprendimento e mi piacerebbe capire come "fare la cosa giusta" in un ambiente che cambia più pesante - seguirà i tuoi link Grazie. –

+0

La memorizzazione nella cache del 'recupero dei dati' è fondamentale, ci vogliono circa 3 secondi per elaborare le migliaia di record che ho - sebbene potrei spendere un po 'di tempo per ottimizzare, non sarà ancora veloce - mentre a causa della lentezza del cambiamento, la memorizzazione dei dati nella cache raramente sarà scaduta! –