2010-06-09 3 views
1

Dans mon application, j'ai un objet Domaine de catégorie. La catégorie a une propriété Parent (de type category).Interrogation d'une jointure auto-référencée avec NHibernate Linq

Donc, dans mon cartographie NHibernate je:

<many-to-one name="Parent" column="ParentID"/> 

Avant je suis passé à NHibernate j'avais la propriété ParentId sur mon modèle de domaine (mis en correspondance avec la colonne de base de données correspondante).

Cela a rendu facile à interroger pour dire toutes les catégories de niveau supérieur (ParentID = 0):

where(c => c.ParentId == 0) 

Cependant, j'ai depuis retiré la propriété ParentId de mon modèle de domaine (en raison de NHibernate) donc je maintenant doivent faire la même requête (en utilisant NHibernate.Linq) comme ceci:

 public IList<Category> GetCategories(int parentId) { 
     if (parentId == 0) 
      return _catalogRepository.Categories.Where(x => x.Parent == null).ToList(); 
     else 
      return _catalogRepository.Categories.Where(x => x.Parent.Id == parentId).ToList(); 
    } 

l'impact réel que je peux voir, est le SQL généré. Au lieu d'un simple 'sélectionner x, y, z des catégories où parentid = 0' NHibernate génère une jointure externe gauche:

SELECT this_.CategoryId as CategoryId4_1_, 
    this_.ParentID  as ParentID4_1_, 
    this_.Name   as Name4_1_, 
    this_.Slug   as Slug4_1_, 
    parent1_.CategoryId as CategoryId4_0_, 
    parent1_.ParentID as ParentID4_0_, 
    parent1_.Name  as Name4_0_, 
    parent1_.Slug  as Slug4_0_ 

des catégories this_ LEFT OUTER JOIN Catégories parent1_ sur this_.ParentID = parent1_.CategoryId O WH this_.ParentID est nul

Ce qui ne semble pas beaucoup moins efficace que ce que j'avais avant.

Existe-t-il une meilleure façon d'interroger ces jointures auto-référencées car il est très tentant de replacer l'ID ParentID sur mon modèle de domaine pour cette raison.

Merci

Répondre

0

Ma première réaction aurait été: oui - c'est la façon dont il est. Sans rien faire, NHibernate essaie toujours de charger l'élément entier - et cela signifie qu'il charge aussi l'élément parent. Est-ce vraiment un problème de performance ou est-ce juste un problème esthétique? Et je ne pense pas que l'inclusion de l'identifiant parent puisse vous aider - car il chargerait toujours l'élément parent avec.

Mais si vous voulez vraiment optimiser cela, lisez l'article suivant http://www.javalobby.org/java/forums/t20533.html. Il s'agit d'Hibernate, mais il vous donne quelques idées sur la façon de gérer cela et une solution (possible) pour votre problème.

+0

J'ai ajouté ParentId à mon modèle, puis dans mon ensemble de mise en correspondance d'hibernation, insérez et mettez à jour pour cette propriété à false. Maintenant, je peux interroger par ID et le sql généré est bien meilleur (sélectionnez x, y, z où parentid == 0). Je pense que je peux probablement vivre avec le parentid collant sur mon modèle pour cette raison. –

+0

bon d'entendre que cela fonctionne .. (J'utilise toujours des critères pour interroger la base de données avec NHibernate donc je ne suis pas vraiment un expert avec NHibernate.Linq ou instructions SQL/NHibernate) – bernhardrusch

Questions connexes