Developer avvisato developer mezzo salvato Smile
Abbiamo un modello di questo genere, fondamentalmente un “albero” con delle “foglie”, foglie che a loro volta possono avere degli attributi:
image
Questo modello è mappato su una struttura relazionale di questo genere:
image
C’è un buon motivo per cui sul db la relazione è tra EntityAttribute e DomainEntity mentre nel dominio è esplicitata su ogni singola entità, ma non è oggetto del contendere odierno Smile
Il tutto è mapato con il fido NHibernate e nei mapping/configurazione è stata attivato il supporto per la cache di secondo livello, facendo un po’ di prove però il Tool per eccellenza NH Proof (spettacolo, siamo inseparabili ormai Smile with tongue out) mi diceva che qualcosa non stava andando come doveva…
image
Succedeva una cosa decisamente curiosa, richieste successive, identiche, producevano un numero di query maggiore di quello della prima richiesta e solo una parte dei dati veniva effetivamente preso dalla cache di secondo livello.
L’applicazione è un servizio WCF ad uso e consumo del nostro CRM, applicazione web, e nello specifico deve ritornare un set di DTO gerarchico che rappresenta le informazioni cercate, il tutto facendo il minor numero possibile di roundtrip verso il db (possibilemente evitando però delle join mostruosoe… Smile)
Alla fine spulciando e studiando, in particolare come funziona il sistema di mapping di NHibernate, ho capito che è essenziale istruirlo affinchè vengano cachate anche le relazioni:
this.HasMany( z => z.ChildZones )
.LazyLoad()

.Cache.ReadWrite();

this.HasMany( z => z.Branches )
.LazyLoad()

.Cache.ReadWrite();

this.HasMany( z => z.Attributes )
.LazyLoad()

.Cache.ReadWrite();
fatto questo “magicamente” il profiler ci dice che non stiamo più toccando inutilmente il db:
image
Il boost dei tempi è percentualmente significativo, in assoluto non ancora perchè le righe sono pochissime.
Al primo giro carichiamo quello che ci serve poi tutto viene correttamente cachato e infatti le richieste successive non toccano più il db ma usano sempre e solo la cache, come si evince anche dalla lista degli statements:
image
.m