2

Je suis en train d'interroger des systèmes mulitple (domaines) pour les informations de sécurité afin que je traite les utilisateurs de domaine et leurs rôles. J'ai configuré mes entités comme indiqué ci-dessous, mais j'ai des problèmes pour configurer la relation domainUser.HasMany dans le remplacement AutoMapper.Comment remplacer la mise en correspondance automatique pour un ID composite, une relation un à plusieurs avec un nhibernate fluide?

Vous remarquerez que je n'ai pas domainUser.DomainUserId et role.RoleId qui rendent ceci beaucoup plus simple (pas de compositeIds.) J'ai évité ces champs parce que j'ai déjà une clé composite naturelle et sera peuplé lorsque je tire ces données du domaine en aval. Si j'ajoute ces clés artificielles, je devrai pré-extraire leurs valeurs avant d'appeler session.Merge (domainUser). J'essaie d'éviter de faire ça.

Les objets d'entité sont évidents (j'espère) mais voici ce que j'ai.

public class DomainUser 
    { 
     public virtual int Domain_Id { get; set; } 
     public virtual string DomainUserLogin { get; set; } 
     public virtual string EmployeeId { get; set; } 

     // extra field removed for breviety 


     public DomainUser() 
     { 
     this.Roles = new List<DomainUserRole>(); 
     } 

     public virtual void AddRole(DomainUserRole role) 
     { 
     role.DomainUser = this; 
     this.Roles.Add(role); 
     } 

     // overrides for equals and getHashCode 
    } 

et

public class DomainUserRole 
    { 
     public virtual DomainUser DomainUser { get; set; } 
     public virtual string DataSegment { get; set; } // Some group of data a user has access to, like US or China 
     public virtual string RoleName { get; set; } 
     public virtual string RoleDescription { get; set; } 

     // extra field removed for breviety 

     // overrides for equals and getHashCode 
    } 

Mon schéma db est assez simple.

alt text http://lh6.ggpht.com/_MV6QGBD11JE/S3iX2qcP_jI/AAAAAAAAEE0/PGIO07BlCSo/s800/Untitled.gif.jpg

J'ai les classes IAutoMappingOverride a commencé comme ça. Mais, je ne sais pas comment configurer le hasMany pour les rôles. Il continue à me donner

NHibernate.FKUnmatchingColumnsException: 
    Foreign key (FK20531BE4163641BB:tblDomainUserRoles [DomainUser])) 
    must have same number of columns as the referenced primary key 
    (tblDomainUsers [Domain_Id, DomainUserLogin]). 

Comment puis-je configurer cette clé étrangère pour utiliser ces deux champs?

public class DomainUserMap : IAutoMappingOverride<DomainUser> 
    { 
     public void Override(AutoMapping<DomainUser> mapping) 
     { 
     mapping.CompositeId() 
      .KeyProperty(user => user.Domain_Id, "Domain_Id") 
      .KeyProperty(user => user.DomainUserLogin, "DomainUserLogin"); 

     // I"ve tried this. 
     // mapping.HasMany(x => x.Roles) 
     // .KeyColumns.Add("Domain_Id") 
     // .KeyColumns.Add("DomainUserLogin"); 

     // also tried this where I define this FK in DB with both fields. 
     // mapping.HasMany(x => x.Roles) 
     // .ForeignKeyConstraintName("FK_tblDomainUserRoles_tblDomainUsers") 

     } 
    } 

    public class DomainUserRoleMap : IAutoMappingOverride<DomainUserRole> 
     { 
      public void Override(AutoMapping<DomainUserRole> mapping) 
      { 
      mapping.CompositeId() 
       .KeyReference(role => role.DomainUser) 
       .KeyProperty(role => role.DataSegment) 
       .KeyProperty(role => role.RoleName);   
      } 
     } 

Répondre

0

J'ai fini par éditer manuellement les fichiers hbm. On dirait que la version la plus récente de Nhibernate parle de ce problème. Voici à quoi ressemble mon fichier hbm.

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true"> 
    <class xmlns="urn:nhibernate-mapping-2.2" name="AAA.Core.Entities.DomainUser, AAA.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`tblDomainUsers`"> 
    <composite-id mapped="false" unsaved-value="undefined"> 
     <key-property name="Domain_Id" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> 
     <column name="Domain_Id" /> 
     </key-property> 
     <key-property name="DomainUserLogin" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> 
     <column name="DomainUserLogin" /> 
     </key-property> 
    </composite-id> 
    ... properties hidden for breviety 
    <bag inverse="true" cascade="all-delete-orphan" lazy="false" name="Roles"> 
     <key> 
     <column name="Domain_Id" /> 
     <column name="DomainUserLogin" /> 
     </key> 
     <one-to-many class="AAA.Core.Entities.DomainUserRole, AAA.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> 
    </bag> 
    </class> 
</hibernate-mapping> 

Voici le fichier pour les rôles.

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true"> 
    <class xmlns="urn:nhibernate-mapping-2.2" name="AAA.Core.Entities.DomainUserRole, AAA.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`tblDomainUserRoles`"> 
    <composite-id mapped="false" unsaved-value="undefined"> 
     <key-property name="DataSegment" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> 
     <column name="DataSegment" /> 
     </key-property> 
     <key-property name="RoleName" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> 
     <column name="RoleName" /> 
     </key-property> 
     <key-many-to-one name="DomainUser" class="AAA.Core.Entities.DomainUser, AAA.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"> 
     <column name="Domain_Id" /> 
     <column name="DomainUserLogin" /> 
     </key-many-to-one> 
    </composite-id> 
    ... properties hidden for breviety 
    </class> 
</hibernate-mapping> 
0

Vous pouvez utiliser une classe de clé composite.

Un exemple d'utilisation d'une classe de clé here at SO. Vous devrez peut-être dérouler et utiliser un fichier HBM au lieu d'utiliser Fluent NHibernate cependant.

Questions connexes