NHibernate, il fetching mode e l'interfaccia IResultTransformer

Non è tantissimo tempo che uso Nhibernate e perciò mi capita spesso di imparare qualcosa di nuovo.

Oggi stavo facendo un po' di fine tuning su un'app windowsforms che è a buon punto. In particolare stavo lavorando sul fetching mode di alcune query.

Il caso era una classica relazione padre figlio (ad es. blogs- blogs item) e volevo caricare tutti i padri  e tutti i figli con un'unica select (disabitando il lazy-loading).

Il primo approccio è stato:

IList blogs = session.CreateCriteria(typeof (Blog))
    .SetFetchMode("Items", FetchMode.Join)
    .List();
    
Il problema è che se nel db ci sono 2 blog ognuno dei quali ha 3 post la lista caricata dal codice sopra conterrà 6 blog (2x3)! In realtà sono le istanze sono 2 ma vengono duplicate nella collezione per effetto della LEFT JOIN che Hibernate esegue sul database.

Naturalmente non è il comportamento che mi aspettavo, quello che  volevo era avere 2 blog con i rispettivi items (3 per ogni blog).

Per ottenere tutto ciò basta specificare una trasformazione sui dati chiamando il metodo SetResultTransformer:

IList blogs = session.CreateCriteria(typeof (Blog))
    .SetFetchMode("Items", FetchMode.Join)
    .SetResultTransformer(new DistinctRootEntityResultTransformer())
    .List();

La classe NHibernate.Transform.DistinctRootEntityResultTransformer si occupa di trasformare la collezione in modo che contenga solo i 2 blog con i rispettivi items.

Print | posted on giovedì 17 maggio 2007 19:48