Question

Je travaille sur un projet qui a un modèle d'objet riche avec divers ensembles de racines globales.

Nous utilisons Château pile (Monorail jusqu'à NHibernate avec ActiveRecord).

Nous avons marqué les racines globales [ActiveRecord(Lazy = true)] comme paresseux et ont personnalisé des routines « désireux » sur notre dépôt pour aggressif un graphe d'objet. Nous utilisons HQL pour définir fetch désireux de notre collection enfant de notre racine,

par exemple. si Account est la racine globale (et marqué paresseux chargé) nous aggressif entités Account .. Order .. Product pour un graphe complet.

Donc pas de surprise à ce jour (je l'espère).

Maintenant, si dans l'exemple ci-dessus, le produit est également marqué [ActiveRecord(Lazy = true)], cela semble arrêter la directive chercher dans la hâte HQL.

Quelqu'un sait-il un moyen de forcer la aggressif d'un objet enfant chargé paresseux ??

Vive ian

Mise à jour :

Ok, voici quelques exemples hql, utilisant l'exemple de « me.yahoo.com/../1 » ci-dessous, nous utilisons IMuliQuery à reslove N + 1 dépendances lors de la récupération sur plusieurs à plusieurs. Nous utilisons aussi explicitement beaucoup à plusieurs classes de cartographie. Par conséquent, notre hql est:

from Account a 'm eager loading the graph
inner join fetch a.AccountsOrders ao 
inner join fetch ao.Order
from Account a 'm eager loading the graph
inner join fetch a.AccountAddresses aa
inner join fetch aa.Address ad
where a.ID = ?

... donc ce exécute les 2 instructions SQL et retourne le jeu de lignes minimale requise, et nous pouvons résoudre ce bas en un seul objet graphique. Nice.

Mais ... si, par exemple, Address a été marqué paresseux chargé (et Order était pas), l'accès à Order ne déclenche pas d'autres instructions SQL, mais l'accès Address ne, en dépit du fait à la fois sont désireux chargés.

Alors, pourquoi n'est pas la Address entité chargée paresseux, au-dessus, désireux par les cheveux la déclaration ci-dessus?

Était-ce utile?

La solution

Pourquoi voulez-vous le comportement avide?

Toutes les relations attributs ActiveRecord ont un paramètre « Lazy = » pour dire à la charge ActiveRecord paresseux l'objet correspondant. Tous sauf Appartient. Appartient vérifie si l'objet dépendant a Lazy = true dans son attribut ActiveRecord et crée ensuite un proxy pour l'objet au lieu de faire une sélection ou joindre.

Pour Lazy le chargement pour travailler toutes les méthodes et propriétés de l'instance de classe doivent être marqués comme virtuel. Cela permet ActiveRecord de construire une classe proxy dynamique.

Maintenant, il peut sembler une bonne idée de chercher le graphique complet pour la performance, mais dans la pratique il est probablement plus lente. J'ai 3 bonnes raisons pour lesquelles:

1.) Appartient a une option Fetch pour définir comment les objets connexes sont tirés. forces FetchEnum.Join AR à utiliser une jointure. FetchEnum. Sélectionnez forces AR à utiliser les instructions select séparés pour chaque objet. Les relations sont de lenteur, nous voyons une amélioration de la performance 10 fois de passer à individu sélectionne. Il n'y a pas de différence dans le code efficace client entre Lazy = true + FetchEnum.Select et désireux.

2.) NHibernate ne cache. Si l'objet est déjà mis en mémoire cache dans la session ou dans le cache de niveau 2, il peut y être sous forme chargée et éviter le travail supplémentaire.

3.) Vous manqueriez sur les avantages de chargement paresseux dans les cas où vous ne l'avez pas fait référence à une partie du graphe d'objet. Encore une fois, vous feriez plus de travail que nécessaire.

Autres conseils

faire une « jointure chercher » sur l'entité Account.Order.Product. Ainsi, au lieu de quelque chose comme ça (ce qui est ce que vous avez probablement déjà):

"from Account a inner join fetch a.Order where a.ID = ?"

Dites-lui de chercher la Order.Product ainsi:

"from Account a inner join fetch a.Order inner join fetch a.Order.Product where a.ID = ?"

De "NHibernate en action", à la page 225:

  

NHibernate vous limite actuellement à aller chercher juste une collection avec impatience.

Cela pourrait expliquer la deuxième requête pour aller chercher les adresses.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top