2009-02-10 7 views
3

J'ai la configuration de la classe suivante pour la persistance en utilisant NHibernateNHibernate et collection compte

public class Person 
{ 
    public string Name { get; set; } 
    public IList<Person> Subordinates { get; set; } 
} 

Maintenant que j'ai une grille avec deux colonnes, « Nom » et « Nombre de Subordonnés » quelle est la meilleure façon de faire ceci dans NHibernate tout en conservant l'utilisation des objets de domaine si possible.

Merci

+0

Voulez-vous lier objet personne à une grille? –

Répondre

9

Vous pouvez créer une classe DTO que vous utilisez pour des rapports/vues d'ensemble par exemple ... Cette classe pourrait ressembler à ceci:

public class PersonView 
{ 
    public string Name{ get;set; } 
    public int NumberOfSubordinates{get;set;}  
} 

Ensuite, vous créez une requête de critères, dans ce critères que vous définissez que vous voulez récupérer toutes les personnes. Toutefois, vous pouvez spécifier que NHibernate ne doit pas renvoyer d'objets Person, mais des objets PersonView. Pour pouvoir faire cela, vous aurez besoin d'utiliser une projection et un AliasToBeanTransformer:

ICriteria crit = new Criteria(typeof(Person)); 

crit.SetProjection (Projections.ProjectionList() 
         .Add (Projections.Property("Name"), "Name") 
         .Add (Projections.Count ("Subordinates"), "NumberOfSubordinates"); 

crit.SetResultTransformer(Transformers.AliasToBean (typeof(PersonView)); 

Quelque chose comme ci-dessus. (Je n'ai pas testé votre situation spécifique). Ensuite, vous devez juste informer NHibernate de l'existence de la classe PersonView, simplement en 'important' cette classe. J'ai un fichier hbm.xml, où j'importe toutes mes classes DTO. Cela ressemble

<hibernate-mapping .. > 
    <import class="PersonView" /> 
</hibernate-mapping> 

Ensuite, NHibernate va générer une requête pour vos critères qui ressemble beaucoup à peu:

SELECT p.Name, COUNT(p.Subordinates) FROM Person 
INNER JOIN Subordinates ON Person.PersonId = Subordinates.PersonID 
GROUP BY p.Name 
+0

Génial, ne connaissait pas les trucs de projections! –

+0

Merci - j'ai essayé d'obtenir un exemple simple de cela ensemble pendant quelques heures maintenant. Cependant, je ne semble pas avoir besoin d'un fichier hbm.xml pour la classe DTO. –

+0

Donc, vous n'avez pas besoin d'importer votre classe? Hmm, je devrais essayer ceci aussi bien il était une fois ... –

0

En supposant que vous avez le HBM corriger cette personne hasMany Subordonnés vous pouvez juste obtenir personne puis appelez Subordinates.Count

Ce processus est modérément inutile si vous avez besoin est le nombre car il sera peupler entièrement toute la collection Subordinates pour vous obtenir le compte. Je pense que vous feriez mieux de créer une méthode qui accepte une personne et vous renvoie le nombre de ses subordonnés et vous utilisez HQL pour faire une fonction de comptage. Si vous ne pouvez pas faire une fonction de comptage direct, vous pouvez lui demander de renvoyer une seule valeur par subordonné correspondant au FK Personne, puis d'appeler .Length ou .Count sur la collection retournée. Cependant, je suppose que HQL devrait pouvoir le compter directement pour vous.

Questions connexes