Ho fatto pace con l'Entity Framework: un minimo di cache!

Andrea Zani

di Andrea Zani, in .NET, venerdì 22 agosto 2008 ore 14.26

Nel post precedente riscontravo che come due richieste sulla stessa entità venisse gestita dall'Entity Framework in maniera - per me - strana, o per meglio dire, non in modo ottimizzato, perché eseguiva due query perfettamente identiche al database. Ovviamente, come mi ha fatto notare giustamente Daniele e Cristian, è un comportamento legittimo, e anzi, sarebbe stato strano se avveniva come io lo avevo immaginato.

Scopro solo ora che nativamente esiste una sorta di cache all'interno dell'Entity Framework, ma la cosa deve essere forzata dal programmatore. Riprendendo l'esempio del mio blog precedente, si deve scrivere:

using (TestModel.TestEntities context = new TestModel.TestEntities())
{
            int colore = 2;
            var a = new TestModel.Articles();
            a.Article = "Art3 " + DateTime.Now.ToString();
            var c = context.Colors.Where(w => w.Id == colore).First();
            a.Colors = c;
            context.AddToArticles(a);
            a = new TestModel.Articles();
            a.Article = "Art4 " + DateTime.Now.ToString();
            //////////////////////////////////////
            object obj = null;
            context.TryGetObjectByKey(
                new System.Data.EntityKey(
                    string.Format("{0}.{1}", context.DefaultContainerName, "Colors"),
                    "Id",
                    colore), out obj);
            if (obj != null)
            {
                // E' presente tra gli oggetti
                c = (TestModel.Colors)obj;
            }
            else
            {
                // Rifaccio la query (*)
                c = context.Colors.Where(w => w.Id == colore).First();
            }
            /////////////////////////////////////
            a.Colors = c;
            context.AddToArticles(a);
            context.SaveChanges();
}

A venirmi in aiuto ci pensa la funzione TryGetObjectByKey che permette di cercare un oggetto per la sua key all'interno del context attuale utilizzato per l'entity framework. La sintassi è un po' intricata, ma risolve un sacco di dubbi. Ora, avviando l'esempio con il profiler avviato, vedo che viene eseguita una sola query per recuperare l'entity del colore...

Ma il TryGetObjectByKey non solo è in grado di prendere il valore se è già stata trattata, ma esegue lui stesso una query nel caso il valore non fosse presente. Il codice qui sopra potrebbe essere scritto in modo più semplice:

using (TestModel.TestEntities context = new TestModel.TestEntities())
{
            int colore = 2;
            var a = new TestModel.Articles();
            a.Article = "Art3 " + DateTime.Now.ToString();
            TestModel.Colors c;
            object obj = null;
            context.TryGetObjectByKey(
                new System.Data.EntityKey(
                    string.Format("{0}.{1}", context.DefaultContainerName, "Colors"),
                    "Id",
                    colore), out obj);
            c = (TestModel.Colors)obj;
            a.Colors = c;
            context.AddToArticles(a);
            a = new TestModel.Articles();
            a.Article = "Art4 " + DateTime.Now.ToString();
            obj = null;
            context.TryGetObjectByKey(
                new System.Data.EntityKey(
                    string.Format("{0}.{1}", context.DefaultContainerName, "Colors"),
                    "Id",
                    colore), out obj);
            c = (TestModel.Colors)obj;
            a.Colors = c;
            context.AddToArticles(a);
            context.SaveChanges();
}

(*) Il codice non viene mai eseguito.

Commenti

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.



Segnala su: Facebook MSDN Social Twitter Segnalo Wikio Diggita Technorati Stumbleupon Google Yahoo FriendFeed Delicious Furl

Nella stessa categoria
I più letti del mese
TagCloud
BLOG INFO
  • 295 post, 201 commenti, 36 trackback
  • Feed blog e contenuti tecnici: RSS
  • Feed blog: RSS Atom
IN EVIDENZA