2010-11-24 12 views
0

J'ai ce scénario:Nhinerbate chargement à l'entité de référence

class A 
{ 
    public virtual int Id { get; set; } 
    public virtual B Child { get; set; } 
} 

class B 
{ 
    public virtual int Id { get; set; } 
} 

Dans la mise en correspondance de classe A, j'ai une référence à la classe B:

map.Reference(a => a.Child).LazyLoad(); 

Maintenant, quand je fais quelque chose comme: En dehors de la sélection normale * de ATable, j'obtiens n sélections de la BTable pour chaque ligne A.

Session.Query<TypeOfA>().Select(a => a); 
Est-ce que le chargement paresseux ne fonctionne pas.

Mes questions sont les suivantes:

  1. Comment je fais ici le travail de lazyload? Puis-je amener les entités A et B dans une seule requête?

Merci,

Répondre

3

chargement Lazy est activée par défaut et devrait réellement fonctionner. S'il y aurait un problème, par exemple s'il ne peut pas générer le proxy pour la classe B, il se plaindrait lors de la création de la fabrique de session.

Etes-vous sûr que les requêtes de B sont effectuées par la requête elle-même, et ne pas être un accès ultérieur à A?

Vous pouvez optimiser l'accès à B de deux manières: les extraire avec A dans une seule requête. (Je ne sais pas à l'aise, c'est la façon xml pour le configurer :)

<many-to-one fetch="join" ...> 

Cela a des problèmes lorsqu'ils sont utilisés avec des listes et pourrait également faire sauter votre requête beaucoup. Ce n'est bien sûr pas un chargement paresseux.

Une autre, très belle et puissante optimisation est la récupération par lots. Il permet de récupérer les instances dans des requêtes distinctes, mais en récupère plusieurs en même temps.

<class name="B" batch-size="20" ...> 

Cela irait chercher 20 B à la fois dans une requête. Il est également disponible pour les listes:

<one-to-many fetch-size="20" ...> 
+0

@Tom: Ce n'est pas vrai. Il y a * anohter * batch-size, qui peut être défini dans la configuration et utilise le traitement par lots d'ADO.NET. Cela permet à NH de créer des lots lors du vidage de la session, pour les instructions de mise à jour et d'insertion. Il est uniquement disponible pour Sql Server. (Voir http://ayende.com/Blog/2006/09/16/BatchingSupportInNHibernate.aspx). Mais la taille de lot dont je parle est pour les requêtes et est indépendante de la base de données. –

+0

mon erreur - j'ai supprimé mon commentaire. –

+0

@Tom: le problème est que NH utilise parfois des termes ambigus. cela rend la compréhension des fonctionnalités très difficile. –

0

Expansion sur la suggestion de Stafan d'utiliser la taille des lots, une recherche rapide sur Google révèle que Fluent NHibernate prend désormais en charge BatchSize pour les requêtes. A partir de la documentation:

ClassMap<T> BatchSize(int size) 

Sets the query batch size for this entity. 

jamais utilisé moi-même, et la documentation est minime (comme beaucoup de FNH), mais vous pouvez peut-être trouver un exemple de code.