2009-01-22 7 views
5

J'ai des problèmes avec quelque chose qui (je pense) devrait être simple, mais ne peut pas trouver d'informations claires.Problème lors de l'utilisation du module Session.Get de nHibernate 2.0 <T> sur une classe avec un ID composite

Dans le scénario où j'ai trois tables, décrivant un domaine dans lequel une personne peut avoir plus d'un emploi:

Personne - a personID, Nom
Job - a JobId, JobName
PersonJob - a personID , JobId, YearsOfEmployment

Remarque: Dans mon modèle d'objet, j'ai des entités représentant chaque table. J'ai cette troisième entité pour représenter la relation personne/travail car il y a des méta-données utiles là-bas (YearsOfEmployment) et n'est pas simplement une simple table de jointure. Donc, si je connaissais le PersonId et le JobId, y a-t-il un moyen simple pour moi d'utiliser la session et de retourner un objet correspondant à ces Ids? Ou, en d'autres termes, puisque je connais déjà les clés primaires, il y a un moyen simple de transformer le SQL "SELECT YearsOfEmployment FROM PersonJob où PersonId = 1 AND JobId = 1" en quelque chose comme:

var keys = new {PersonId=1, JobId=2};
PersonJob obj = Session.Get<PersonJob>(keys);

BTW: cartes ressemblerait à quelque chose comme ceci:

<class name="Person" table="dbo.Person" lazy="true"> 
    <id name="PersonId"> 
    <generator class="native"/> 
    </id> 
    <property name="Name"/> 
</class> 
<class name="Job" table="dbo.Job" lazy="true"> 
    <id name="JobId"> 
    <generator class="native"/> 
    </id> 
    <property name="JobName"/> 
</class> 
<class name="PersonJob" table="dbo.PersonJob" lazy="true"> 
    <composite-id> 
    <key-property name="PersonId"></key-property> 
    <key-property name="JobId"></key-property> 
    </composite-id> 
    <property name="YearsOfEmployment"/> 
</class> 

Répondre

8

Eh bien, je répondais à ma propre question. Je pense que poster votre problème est presque aussi cathartique que de parler avec quelqu'un. Si je devais faire le composite id PersonJob un composant ou classe, à savoir

<class name="PersonJob" table="dbo.PersonJob" lazy="true"> 
    <composite-id name="PersonJobKey" class="PersonJobKey"> 
     <key-property name="PersonId"></key-property> 
     <key-property name="JobId"></key-property> 
    </composite-id> 
</class> 

Alors je peux simplement faire ceci:

PersonJobKey key = new PersonJobKey() { PersonId = 1, JobId = 1 }; 
PersonJob obj = Session.Get<PersonJob>(key); 
int yearsOfEmployment = obj.YearsOfEmployment; 

cool. J'espère que cela aide quelqu'un d'autre à comprendre cela ...

+0

vaudraient peut-être ajouter l'ensemble de la classe PersonJobKey que je suis en train d'essayer de savoir quelle classe je dois passer outre. –

3

Merci d'avoir posté la réponse ci-dessus, je la regardais contre un objet que j'ai cartographié où la clé composite n'a pas de nom ou de classe. Lorsque j'ai essayé de créer une classe pour représenter la clé composite, cela a changé la façon dont l'objet se comportait lorsqu'il était utilisé par un autre code. Aussi je voulais écrire quelque chose comme;

Session.Get<SalesRepArea>(new { AreaCode = "ACode", RegionCode = "RCode"}); 

Je trouve que NHibernate ne pouvait pas beaucoup de sens de l'objet anonyme, mais je ne compte que je ne suis pas besoin d'un nom pour ma clé composite, ou d'un type de classe. Ce que fait la méthode nHibernate Get après, en fait, est un objet transitoire afin qu'il puisse obtenir son objet équivalent à partir de la base de données (c'est pourquoi vous devez surcharger la méthode equals dans votre classe C# pour que la clé composite fonctionne). Donc, pour la carte suivante

<class name="SalesRepArea"> 
    <composite-id> 
     <key-property 
     name="AreaCode" column="AreaCode" type="String" length="12" /> 
     <key-property 
     name="RegionCode" column="RegionCode" type="String" length="12" /> 
    </composite-id> 

J'écris un peu moins de code, et se passer de l'objet représentant la clé pour obtenir

SalesRepArea myArea = Session.Get<SalesRepArea>(
    new SalesRepArea() 
    { 
     AreaCode = "ACode", 
     RegionCode = "RCode" 
    } 
); 

Je ne dis pas que la méthode clé nommée est mauvais, moins de code n'est pas toujours meilleur, c'est juste pour montrer qu'Hibernate cherche l'objet dans lequel se trouve la clé pour obtenir l'objet spécifique de la base de données.Si je me trompe s'il vous plaît faites le moi savoir, mais j'espère que cela aide, car j'avais un peu de mal avec cela.

Merci,

Mark

Questions connexes