Précédent   Forum du club des développeurs et IT Pro > Dotnet > Accès aux données > NHibernate
NHibernate Forum d'entraide sur l'utilisation du mappeur objet/relationnel NHibernate.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 11/04/2012, 17h03   #1
Lutetia
Invité de passage
 
Inscription : septembre 2011
Messages : 3
Détails du profil
Informations forums :
Inscription : septembre 2011
Messages : 3
Points : 1
Points : 1
Par défaut Migration NHbernate 1.2 vers 3.2

Bonjour,

Je suis en train d'effectuer une migration d'un projet sous NHibernate 1.2 vers la version 3.2 et j'ai un problème au niveau du chargement d'une collection.

En gros j'ai une classe "Carton" et une classe "Boite", un carton peut contenir plusieur boites. Dans ma classe Carton j'ai une propriété "Inventaire" en virtual qui permet d'accéder à ces cartons.

Au lancement de mon appli tout va bien, ma requête va bien récupérer mon carton, mais la propriété reste vide. Il me semble que lazy loading par défaut est activé, j'ai essayé de mettre ce lazy à false un peu partout mais rien n'y fait, je vois bien que le chargement met plus de temps mais rien n'est récupéré.

J'ai bien évidemment fait le mapping puisque cela fonctionnnait très bien en version 1.2.

Voici mon app.config :
Code :
1
2
3
4
5
6
7
8
9
10
11
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
    <session-factory>
            <property name="dialect">NHibernate.Dialect.FirebirdDialect</property>
      <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
      <property name="connection.driver_class">NHibernate.Driver.FirebirdClientDriver</property>
      <property name="connection.connection_string">server=dev;User=toto;Password=tata;Database=titi;Charset=ISO8859_1;</property>
      <property name="show_sql">true</property>
      <property name="query.substitutions">true 1, false 0</property>
      <mapping assembly="CACAO_Framework"/>
    </session-factory>
  </hibernate-configuration>
La requête qui récupère mon carton:
Code :
1
2
3
4
5
6
7
8
 
public static Carton GetCartonById(long id)
        {
            IQuery srv = GetCurrentSession().CreateQuery("from Carton c where c.Id  = :id");
            srv.SetParameter("id", id);
            Carton result = srv.UniqueResult<Carton>();
            return result;
        }
Est-ce une histoire de lazy loading ?
Ou comment dans ma requête puis je faire un "Load" comme en Linq ?
Des idées ?

Merci d'avance.
Lutetia est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/07/2012, 13h57   #2
Vimaire
Membre habitué
 
Homme Alexandre Trigueros
Architecte C#
Inscription : février 2003
Messages : 74
Détails du profil
Informations personnelles :
Nom : Homme Alexandre Trigueros
Localisation : France, Hérault (Languedoc Roussillon)

Informations professionnelles :
Activité : Architecte C#

Informations forums :
Inscription : février 2003
Messages : 74
Points : 133
Points : 133
Bonjour,
par un "Load", tu veux dire une commande comme :
Code :
1
2
var session = GetCurrentSession();
return session.Load<Carton>(id);
Les méthodes Load & Get sont déjà existantes dans la session.

Attention : Get te renverra null si il ne trouve pas l'id et Load te renverra un proxy qui lancera une exception si l'objet n'existe pas quand tu voudra y accéder.

Pour forcer le fetching de la collection, tu peux la désactiver dans le mapping (lazy="false") forcer à faire un jointure ("fetch=join")

d'autres méthodes existent également pour le hql, le requetage par criteria & QueryOver

Pour le hql :
Code :
from Carton c where c.Id  = :id left join fetch c.Inventaire
Pour l'api criteria - setFetchMode
Code :
1
2
3
4
5
6
var result = GetCurrentSession()
                .CreateCriteria<Carton>()
                .SetFetchMode("Inventaire", FetchMode.Eager)
                .Add(Restrictions.Where<PDCInfo>(carton => carton.Id == id))
                .SetResultTransformer(Transformers.DistinctRootEntity)
                .UniqueResult<Carton>();
et enfin pour la queryOver :
Code :
1
2
3
4
5
6
var result = GetCurrentSession()
                .QueryOver<Carton>()
                .Where(carton => carton.Id == id)
                .Fetch(carton => carton.Inventaire).Eager
                .TransformUsing(Transformers.DistinctRootEntity)
                .SingleOrDefault();
Si tu as systématiquement besoin de l'information inventaire, autant la mapper en eager / join dans le mapping.
Sinon, faire une requete, la plus simple possible et spécifier le résultat.

Attention, avec les requêtes à jointure, tu peux te retrouver avec des résultats en double. La raison de la ligne du "Transformers.DistinctRootEntity" c'est pour filtrer par entité racine. il te faudra aussi la spécifier sur l'objet IQuery si tu utilises le hql.

J'ai un peu de mal également à comprendre pourquoi tu met le hql directement dans le code ? perso, je préfère le sortir dans le mapping de manière a n'avoir qu'une grosse partie qui concerne la base de données.

Bref, dans tous les cas, tu as de quoi avancer !

Bonne après midi.
Vimaire est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 22h53.


 
 
 
 
Partenaires

Hébergement Web