Как переопределить автоматическое сопоставление для составного идентификатора, отношения один-ко-многим с беглым nhibernate? - PullRequest
2 голосов
/ 15 февраля 2010

Я опрашиваю несколько систем (доменов) на предмет информации о безопасности, поэтому я имею дело с domainUsers и их ролями. У меня настроены объекты, как показано ниже, но у меня возникают проблемы при настройке отношения domainUser.HasMany в переопределении AutoMapper.

Вы заметите, что у меня нет domainUser.DomainUserId и role.RoleId, которые делают это намного проще (без CompositIds.) Я избегал этих полей, потому что у меня уже есть естественный составной ключ, и быть заполненным, когда я получаю эти данные из нижестоящего домена. Если я добавлю эти искусственные ключи, мне придется предварительно извлечь их значения, прежде чем я вызову session.Merge (domainUser). Я пытаюсь избежать этого.

Объекты сущности очевидны (я надеюсь), но вот что у меня есть.

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
   }

и

   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
   }

Моя схема БД довольно проста.

альтернативный текст http://lh6.ggpht.com/_MV6QGBD11JE/S3iX2qcP_jI/AAAAAAAAEE0/PGIO07BlCSo/s800/Untitled.gif.jpg

У меня классы IAutoMappingOverride запущены вот так. Но я не знаю, как настроить hasMany для ролей. Это продолжает давать мне

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

Как настроить этот внешний ключ для использования обоих этих полей?

   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);         
          }
       }

Ответы [ 2 ]

0 голосов
/ 17 февраля 2010

Я закончил редактирование файлов hbm вручную. Похоже, самая последняя сборка на беглом Nhibernate решает эту проблему. Вот как выглядит мой файл 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>

вот файл для ролей.

<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 голосов
/ 16 февраля 2010

Вы можете использовать класс составного ключа.

Пример использования класса ключей здесь, в SO . Однако вам, возможно, придется отказаться от использования файла HBM вместо использования Fluent NHibernate.

...