我该如何映射到一个连接子类比父母的ID的不同的列?(How can I map to a joine

2019-09-23 11:41发布

我有一个工作棕地数据库,并正在尝试配置一个子类地图,加入到它的子类具有比指定ID的其他列。 该login表有一个主键列login_sk我想为它的ID使用哪个。 它加入到通过两个表login_cust_id柱(使事情更有趣毗邻表中相应列的名称不同)。 如果我设置login_cust_id为用户映射的id其加入到它的子类如预期。 对于我希望是显而易见的原因,我不想用login_cust_id的ID为我的用户对象。

public class UserMap : ClassMap<IUser>
{
    public UserMap()
    {
        Table("login");
        Id(x => x.Id).Column("login_sk"); // want to setup map like this

        // if used instead this works for subclass joining / mapping
        // Id(x => x.Id).Column("login_cust_id");
        // would prefer to only reference login_cust_id for subclass mapping
    }
}

public class CustomerUserMap : SubclassMap<CustomerUser>
{
    public CustomerUserMap()
    {
        Table("customer");
        Map(c => c.DisplayName, "cust_mail_name");
        Map(c => c.RecordChangeName, "cust_lookup_name");
        KeyColumn("cust_id");
    }
}

public class EntityUserMap : SubclassMap<EntityUser>
{
    public EntityUserMap()
    {
        Table("entity");
        Map(c => c.DisplayName, "entity_name");
        KeyColumn("entity_id");
    }
}

我想要做的是只使用login_cust_id加入到子类时,列。 是否有一个流畅的映射设置,让我来指定这个? 如果不是一个能说会道的映射是有,将工作定期NHibernate的XML映射? 我宁愿甚至没有映射列,并只使用它,如果可能的加盟。 如果它有助于有一个潜在的鉴别列login_holder_type指示哪个表加入到。

它没有想到要建立一个IClassConvention但在经过戳后IClassInstance我不能确定,这将有助于我的任何设置。

public class UserIdConvention : IClassConvention, IClassConventionAcceptance
{

    public void Apply(IClassInstance instance)
    {
        // do something awesome with instance.Subclasses to
        // specify the use of login_cust_id for subclass joining...
    }

    public void Accept(IAcceptanceCriteria<IClassInspector> criteria)
    {
        criteria.Expect(x => typeof(User).Equals(x.EntityType));
    }
}

缺乏一个人口子类集合了通过实例的缘故,我找哪个更具体的检查IParentInspector似乎是。 不幸的是流利的NHibernate不会出现有相应的实现为IParentInstanceIParentConventionIParentConventionAcceptance像它的IJoinedSubclassInspector 。 虽然我大概可以实现我自己之前,我做我想确保我是不是找错了树。

这算哪门子的子类ID的调整甚至可能吗? 我缺少的东西在我的任一地图或明显的功能NHibernate约定的命名空间 ? 我该如何映射到一个连接子类有不同的列/性能比父母的id?

Answer 1:

我能想到的三种可能的解决您的问题,请在下方看到我的发现。

方案1:基于分辨映射与加入

我最初的想法是使用基于鉴别映射继承模型,包含了楼盘,即加入每个子类

<class name="IUser" abstract="true" table="login">
    <id name="Id" column="login_sk">
        <generator class="identity"/>
    </id>
    <discriminator column="login_holder_type" not-null="true" type="System.String"/>

    <subclass name="CustomerUser" discriminator-value="Customer">
        <join table="customer" >
          <key column="cust_id" property-ref="login_cust_id" />
          <property name="DisplayName" column="cust_mail_name"/>
          <property name="RecordChangeName" column="cust_lookup_name" />
        </join>
    </subclass>

    <subclass name="EntityUser" discriminator-value="Entity">
      <join table="entity" >        
        <key column="entity_id" property-ref="login_cust_id" />
        <property name="CompanyName"/>
      </join>
    </subclass>
</class>

不幸的是,在这个时候支持此功能在Hibernate中而不是在NHibernate的。 请参阅这里和这里的优秀票。 有些工作已经朝着增加这个功能,可以看出这个叉GitHub上。

方案2:多到一个基于鉴别映射

另一种选择是仍然使用基于分辨映射,而是使用一个many-to-one在每个子类,这样可以让你加入使用作为property-ref外键的映射。 这点是需要所有的客户和实体表的属性不同的类的缺点,但是是一个可行的解决方案。

<class name="IUser" abstract="true" table="login">
    <id name="Id" column="login_sk">
        <generator class="identity"/>
    </id>
    <discriminator column="login_holder_type" not-null="true" type="System.String"/>

    <subclass name="CustomerUser" discriminator-value="Customer">
        <many-to-one name="CustomerProps" property-ref="login_cust_id" />
    </subclass>

    <subclass name="EntityUser" discriminator-value="entity">
        <many-to-one name="EntityProps" property-ref="login_cust_id" />     
    </subclass>
</class>

<class name="CustomerProps" Table="customer" >
  <id name="Id" column="cust_id">
    <generator class="assigned"/>
  </id>
  <property name="DisplayName" column="cust_mail_name"/>
  <property name="RecordChangeName" column="cust_lookup_name" />
</class>

<class name="EntityProps" Table="entity" >
  <id name="Id" column="entity_id">
    <generator class="assigned"/>
  </id>
  <property name="CompanyName"/>
</class>

方案3:基于鉴别映射连接来更新视图

最后一个选项是建立在DB为其中包含login_sk领域的客户和实体表可更新视图。 然后,您可以使用Join每个子类中,你将不需要property-ref

<class name="IUser" abstract="true" table="login">
    <id name="Id" column="login_sk">
        <generator class="identity"/>
    </id>
    <discriminator column="login_holder_type" not-null="true" type="System.String"/>

    <subclass name="CustomerUser" discriminator-value="Customer">
        <join table="customerView" >
          <key column="login_sk" />
          <property name="DisplayName" column="cust_mail_name"/>
          <property name="RecordChangeName" column="cust_lookup_name" />
        </join>
    </subclass>

    <subclass name="EntityUser" discriminator-value="Entity">
      <join table="entityView" >        
        <key column="login_sk" />
        <property name="CompanyName"/>
      </join>
    </subclass>
</class>


文章来源: How can I map to a joined subclass with a different column than the id of parent?