365 messaggi dal 08 febbraio 2009
Salve a tutti.

Volevo utilizzare Entity Framework solo per le letture (quindi per mappare le classi ed andare a leggerle).

Il motivo è che il DB viene aggiornato dall'applicazione attuale che è scritta in un altro linguaggio, quindi non può usare EntityFramework.

Per cui, per farmi un po' di esperienza, volevo fare un po' di prove usando EntityFramework.

Non sono sicuro, però mi pare di aver capito che il DbContext se ha una classe già caricata in memoria, non accede di nuovo al DB per leggerla.
Questo ottimizza i tempi se a fare le update è sempre il DbContext. Ma se il DB viene scritto da un'altra sorgente dati, come posso fare per "obbligare" il DbContext a rileggere sempre i dati?

PS: Se invece ho capito male e il DbContext si occupa di avere sempre e solo una versione dell'oggetto (quindi un solo cliente in memoria con ID = 1) ma che tutte le volte che faccio una query legge i dati dal DB e aggiorna quell'oggetto, allora scusatemi!


PS2: Per "ottimizzare" i tempi di accesso ho disattivato il Tracking delle classi (perchè tanto sono in sola lettura). Ci sono altre cose che posso impostare per velocizzare l'applicativo di interrogazione?


Grazie mille
5.610 messaggi dal 09 febbraio 2002
Contributi
ciao,
in merito al miglioramento delle performance, trovi molte in formazioni utili in questi due articoli di Stefano Mostarda.
http://www.linqitalia.com/articoli/entity-framework/ottimizzare-performance-applicazione-entity-framework.aspx
http://www.linqitalia.com/articoli/entity-framework/migliorare-performance-accesso-dati-entity-framework-41.aspx

Leggi anche qui
http://msdn.microsoft.com/en-us/library/cc853327.aspx

JoeRuspante ha scritto:

Non sono sicuro, però mi pare di aver capito che il DbContext se ha una classe già caricata in memoria, non accede di nuovo al DB per leggerla.

In realtà ci accede (la query viene eseguita di nuovo) ma se anche si fossero verificati cambiamenti li scarta :)
Questo è un comportamento che puoi modificare a tua discrezione agendo sulla proprietà MergeOption delle collezioni ObjectSet<T>. Tuttavia, lavorando con DbContext, tu hai dei DbSet<T> che però non espongono questa proprietà. Ci puoi arrivare lo stesso per vie traverse:

var customers = ((IObjectContextAdapter) tuoDbContext).ObjectContext.CreateObjectSet<Customer>();
//istruisco EF che se trova modifiche nel DB non deve ignorarle
//ma deve usarle per aggiornare l'entità che magari si era già materializzata nel contesto dopo una prima query
customers.MergeOption = MergeOption.OverwriteChanges; 
//faccio la query sui customers ottenuti in questo modo
var query = from c in customers
            ...

Dario Santarelli lo spiega in maniera molto minuziosa in questo suo articolo su Identity Map, il pattern che anche Entity Framework adotta nel garantire di tenere in memoria una e una sola istanza di ciascuna entità.
http://dariosantarelli.wordpress.com/2011/11/26/entity-framework-v4-identity-map-pattern/

ciao
Modificato da BrightSoul il 27 gennaio 2012 23.52 -

- So what you're saying is, if we get in trouble, there's no one to help us out?
- I'm afraid not.
- Fantastic!
365 messaggi dal 08 febbraio 2009
Grazie mille!

Per quanto riguarda le "performance", sto provando a leggere un po' di cose in giro (ti ringrazio per i link, appena finiti quelli in elenco, leggerò quelli da te postati).

Per quanto riguarda l'accesso al DB, invece, ho fatto la classica prova "spartana": ho letto i dati di una classe con EF, ho cambiato a mano i dati sul DB ed ho provato a rileggerli.

Non so perchè, però senza configurare quanto mi avevi detto, la procedura mi ha già riportato i dati nuovi (quindi l'esito che volevo io).

Pertanto per il momento tengo i tuoi riferimenti qualora smettesse di funzionare, per il momento però non mi pongo troppo il problema visto che mi sta funzionando! :-D
5.610 messaggi dal 09 febbraio 2002
Contributi
ciao,

JoeRuspante ha scritto:

Non so perchè, però senza configurare quanto mi avevi detto, la procedura mi ha già riportato i dati nuovi (quindi l'esito che volevo io).

Forse nella tua query LINQ hai proiettato l'entità su un altro tipo?
Se seleziono l'entità, allora verrà gestita dall'ObjectStateManager:
var query = from c in context.Customers
            select c;

Invece, se la proietto - ad esempio - su un tipo anonimo, allora non verrà gestita perché non si tratta più di un'entità appartenente al modello concettuale. Ogni esecuzione della query mi restiturà sempre dati "freschi".
var query = from c in context.Customers
            select new {c.CustomerID, c.CompanyName};


E' possibile che sia questo il motivo?

EDIT: no, non credo. Vedo dall'altro thread che usi .AsNoTracking(), quindi probabilmente dipende da quello. Non essendo mantenuta in cache, l'entità ti si rimaterializza sempre di nuovo con dati freschi.

ciao
Modificato da BrightSoul il 01 febbraio 2012 00.22 -

- So what you're saying is, if we get in trouble, there's no one to help us out?
- I'm afraid not.
- Fantastic!
365 messaggi dal 08 febbraio 2009
Grazie mille.
Comunque il mio caso era il mix (sia il NoTracking che la select con "new").

Quindi meglio se mi pongo il problema...

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.
Community
Ultimi messaggi
UTENTI ONLINE
In primo piano

I più letti di oggi

Media
In evidenza
MISC