如何覆盖复合Id的自动映射,即与fluent nhibernate的一对多关系?

如何覆盖复合Id的自动映射,即与fluent nhibernate的一对多关系?,nhibernate,fluent-nhibernate,nhibernate-mapping,parent-child,fluent,Nhibernate,Fluent Nhibernate,Nhibernate Mapping,Parent Child,Fluent,我正在轮询多个系统(域)以获取安全信息,因此我正在处理域用户及其角色。我的实体设置如下所示,但设置domainUser时遇到问题。AutoMapper覆盖中存在许多关系 您会注意到,我没有domainUser.DomainUserId和role.RoleId,这使得这更简单(没有compositeid)。我避免了这些字段,因为我已经有了一个自然的复合键,当我从下游域提取数据时,它将被填充。如果我添加这些人工键,我必须在调用session.Merge(domainUser)之前预取它们的值。我尽量

我正在轮询多个系统(域)以获取安全信息,因此我正在处理域用户及其角色。我的实体设置如下所示,但设置domainUser时遇到问题。AutoMapper覆盖中存在许多关系

您会注意到,我没有domainUser.DomainUserId和role.RoleId,这使得这更简单(没有compositeid)。我避免了这些字段,因为我已经有了一个自然的复合键,当我从下游域提取数据时,它将被填充。如果我添加这些人工键,我必须在调用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
   }
我的数据库模式非常简单

我已经让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);         
          }
       }
公共类DomainUserMap:IAutoMappingOverride
{
公共无效替代(自动映射)
{
mapping.CompositeId()
.KeyProperty(user=>user.Domain\u Id,“Domain\u Id”)
.KeyProperty(user=>user.DomainUserLogin,“DomainUserLogin”);
//我试过这个。
//mapping.HasMany(x=>x.Roles)
//.KeyColumns.Add(“域\u Id”)
//.KeyColumns.Add(“DomainUserLogin”);
//我还尝试了在DB中用这两个字段定义FK。
//mapping.HasMany(x=>x.Roles)
//.ForeignKeyConstraintName(“FK\u tblDomainUserRoles\u tblDomainUsers”)
}
}
公共类DomainUserRoleMap:IAutoMappingOverride
{
公共无效替代(自动映射)
{
mapping.CompositeId()
.KeyReference(角色=>role.DomainUser)
.KeyProperty(角色=>role.DataSegment)
.KeyProperty(role=>role.RoleName);
}
}

我确实手工编辑了hbm文件。看起来最新的基于fluent 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>

…为breviety隐藏的属性
这是角色的文件

<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>

…为breviety隐藏的属性

我确实手工编辑了hbm文件。看起来最新的基于fluent 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>

…为breviety隐藏的属性
这是角色的文件

<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>

…为breviety隐藏的属性