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.
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
- C# e Net 6 in Kubernetes con Prometheus e Grafana, il 12 gennaio 2022 alle 21:58
- Snaturare Kubernetes evitando i custom container Docker, il 6 gennaio 2022 alle 19:40
- Provando Kaniko in Kubernetes come alternativa a Docker per la creazione di immagini, il 18 dicembre 2021 alle 20:11
- Divertissement con l'OpenID e Access Token, il 6 dicembre 2021 alle 20:05
- Operator per Kubernetes in C# e Net Core 6., il 28 novembre 2021 alle 19:44
- RBAC in Kubernetes verso gli operator, il 21 novembre 2021 alle 20:52