2010-07-14 6 views
0

J'ai une table de produit qui a un grand nombre à plusieurs par rapport à lui-même (en utilisant un grand nombre à plusieurs tableau à deux colonnes) et je l'ai mis en place dans Fluent NHibernate avec le code suivant:Comment est-ce que j'utilise le Nhibernate Fluent plusieurs-à-plusieurs pour une performance optimale?

public class ProductConfiguration : ClassMap<Product> 
{ 
    public ProductConfiguration() 
    { 
     Table("Product"); 
     Id(p => p.Id).GeneratedBy.Guid(); 

     Map(p => p.Name).Not.Nullable().Length(254); 
     Map(p => p.Description).Not.Nullable().Length(1000); 
     Map(p => p.CreatedAt).Not.Nullable(); 

     HasManyToMany(p => p.CrossSell) 
      .Table("ProductCrossSell") 
      .ParentKeyColumn("Id") 
      .ChildKeyColumn("ProductId"); 
    } 
} 

Mon application MVC a deux pages qui utilise cette configuration:

  • Index - Utilise une méthode générique référentiel GetAll pour afficher tous les produits.
  • Détail - Utilise une méthode de référentiel générique GetById pour afficher un produit et tous les produits de vente croisée associés dans la réalisation many-to-many.

On dirait que NHibernate est réglé sur lazyload nombreux à plusieurs par défaut alors quand je lance l'application et le regarder dans profileur je peux voir qu'il ne lazyload nombreux à plusieurs avec les éléments suivants alerte "L'utilisation de transactions implicites est déconseillée".

  1. Comment puis-je me débarrasser de cette alerte? Je n'ai trouvé aucune information sur la façon d'emballer un LazyLoad dans une transaction pour se débarrasser de l'alerte. Est-ce même possible?
  2. Existe-t-il un moyen de ne pas le charger en disant à NHibernate que chaque fois que je demande GetById, assurez-vous de joindre les tables et d'obtenir tout en une requête? J'ai essayé d'utiliser .Fetch.Join() dans le mappage plusieurs-à-plusieurs, mais cela a également affecté ma requête GetAll qui affiche maintenant un ensemble de résultats joint qui est incorrect.

Quelle est la meilleure approche pour ce genre de scénario simple?

Merci

Répondre

0
  1. La façon de se débarrasser de l'avertissement est d'accéder au graphe d'objets et remplir complètement les éléments de l'interface utilisateur à l'intérieur d'une seule transaction.

  2. Pas par configuration. Vous pouvez créer une requête HQL qui recherche rapidement l'association et utilise cette requête pour une vue spécifique. Je voudrais rester avec le chargement paresseux et ne pas faire cette optimisation à moins que nécessaire. Le HQL serait:


return session.CreateQuery("from ProductionConfiguration pc join fetch pc.CrossSell where pc.Id = ?") 
    .SetGuid(0, id) 
    .List<ProductConfiguration>(); 
+0

Jamie, diriez-vous que la « Utilisation des transactions implicites est déconseillée » alerte est pas une grosse affaire dans ce cas? Je ne démarre pas l'itération à travers l'association jusqu'à la vue afin que le lazyload se déclenche toujours en dehors de la portée de la transaction. Le seul moyen de contourner le problème est de charger la transaction dans la transaction, comme vous l'avez dit. – Thomas

+0

Je ne m'inquiéterais pas à ce sujet, surtout dans une opération de lecture. Dans presque tous les cas, je pense que vous pouvez l'ignorer en toute sécurité. Ce n'est qu'un avertissement après tout. :-) –

0

Toutes les collections sont chargées dans paresseusement NHibernate par défaut.

Vous devez être déclenchez le chargement d'un appel d'une sorte (peut-être même avec les montres de débogage)