C# nHibernate中的子类表映射

C# nHibernate中的子类表映射,c#,nhibernate,nhibernate-mapping,subclass,C#,Nhibernate,Nhibernate Mapping,Subclass,首先,对文字墙表示抱歉 我有下面的模式。请注意,User\u Contact中可能包含空值 在类级别上,它将按照以下方式实现 public abstract class User : EntityBase<Guid>, IAggregateRoot { public User() { } public virtual string FirstName { get; set; } public virtual string LastName

首先,对文字墙表示抱歉

我有下面的模式。请注意,
User\u Contact
中可能包含空值

在类级别上,它将按照以下方式实现

public abstract class User : EntityBase<Guid>, IAggregateRoot
{
    public User()
    {

    }

    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }

    protected abstract override void Validate();
}

public class SiteUser : User
{
    public SiteUser() { }

    public virtual Guid ApplicationId { get; set; }
    public virtual string UserName { get; set; }
    public virtual string LoweredUserName { get; set; }
    public virtual string MobileAlias { get; set; }
    public virtual bool IsAnonymous { get; set; }
    public virtual DateTime LastActivityDate { get; set; }

    protected override void Validate()
    { 
        if (this.ApplicationId == Guid.Empty)
            base.AddBrokenRule(UserBusinessRules.ApplicationIdRequired);

        if (this.UserName.IsNullOrEmpty())
            base.AddBrokenRule(UserBusinessRules.UserNameRequired);

        if (this.LoweredUserName.IsNullOrEmpty())
            base.AddBrokenRule(UserBusinessRules.LoweredUserNameRequired);

        if (this.LastActivityDate == DateTime.MinValue)
            base.AddBrokenRule(UserBusinessRules.LastActivityDateRequired);

    }
}

public class SiteContact : SiteUser
{

    public SiteContact() 
    {
    }


    public virtual int ExternalID { get; set; }
    //All the rest...

    protected override void Validate()
    { 
        //validate
    }
}
但我一辈子都无法在hbm映射文件中解决这个问题。为了简单起见,这里是省略了一些字段的文件

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="MyProject.Namespaces.Model.Entities" assembly="MyProject.Namespaces.Model">


  <class name="User" table="User_Contact" lazy="true" abstract="true">

    <id name="ID" column="UserId" type="guid">
      <generator class="guid" />
    </id>

    <discriminator column="ContactID" formula="(CASE WHEN ContactID IS NOT NULL THEN 1 ELSE 0 END)" />

    <property name="FirstName">
      <column name="FirstName" sql-type="nvarchar(500)" not-null="true" />
    </property>

    <property name="LastName">
      <column name="LastName" sql-type="nvarchar(500)" not-null="true" />
    </property>

    <subclass name="SiteContact" discriminator-value="1">
      <join table="Contact">
        <key column="ContactID" /> //I assume the problem is here. I have tried adding foreign-key="ContactID" to no success

        <property name="ExternalID" insert="false" update="false">
          <column name="ExternalID" sql-type="int" not-null="true" />
        </property>

        //The rest of the mapped columns

      </join>
      <join table="aspnet_Users">
        <key column="UserId" />

        <property name="ApplicationId">
          <column name="ApplicationId" sql-type="guid" not-null="true" />
        </property>

        <property name="UserName">
          <column name="UserName" sql-type="nvarchar(256)" not-null="true" />
        </property>

        <property name="LoweredUserName">
          <column name="LoweredUserName" sql-type="nvarchar(256)" not-null="true" />
        </property>

        <property name="MobileAlias">
          <column name="MobileAlias" sql-type="nvarchar(16)" not-null="false" />
        </property>

        <property name="IsAnonymous">
          <column name="IsAnonymous" sql-type="bit" not-null="true" />
        </property>

        <property name="LastActivityDate">
          <column name="LastActivityDate" sql-type="datetime" not-null="true" />
        </property>

      </join>
    </subclass>

    <subclass name="SiteUser" discriminator-value="0">
      <join table="aspnet_Users">
        <key column="UserId" />

        //blah blah blah

      </join>
    </subclass>

  </class>

</hibernate-mapping>

//我想问题就在这里。我尝试添加外键=“ContactID”但未成功
//其余的映射列
//废话废话

希望有人能告诉我,关于这个映射,我是否在正确的轨道上,也许能提供一些指导?

这似乎是一个非常复杂的映射方式。我不确定在这种情况下,您希望通过使用继承获得什么好处,我建议改用组合(即每个表有一个类并映射关系)

话虽如此,你大概有你的理由,因此我建议以下几点来实现我认为你想要的:

  • 将SiteUser类映射为基类,并使用从User_Contact到aspnet_用户的联接(因此在映射中不要将User作为基类)
  • 然后使用连接的子类映射而不是子类将SiteContact映射为子类,这样就不需要使用鉴别器
    这似乎是一个相当复杂的映射方式。我不确定在这种情况下,您希望通过使用继承获得什么好处,我建议改用组合(即每个表有一个类并映射关系)

    话虽如此,你大概有你的理由,因此我建议以下几点来实现我认为你想要的:

  • 将SiteUser类映射为基类,并使用从User_Contact到aspnet_用户的联接(因此在映射中不要将User作为基类)
  • 然后使用连接的子类映射而不是子类将SiteContact映射为子类,这样就不需要使用鉴别器
    事实上,你的思路是正确的,我们确实有我们的理由来解释为什么我们想采用这种方法,但最终决定,这正是你所说的“太复杂了”。因此,我们最终重组了模式。尽管如此,我仍然对如何实现这种映射感到好奇,看来您的解决方案会奏效。非常感谢。事实上你走得很对,我们有我们的理由来解释为什么我们想采取这种方法,但最终决定,这正是你所说的“太复杂了”。因此,我们最终重组了模式。尽管如此,我仍然对如何实现这种映射感到好奇,看来您的解决方案会奏效。非常感谢你。
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="MyProject.Namespaces.Model.Entities" assembly="MyProject.Namespaces.Model">
    
    
      <class name="User" table="User_Contact" lazy="true" abstract="true">
    
        <id name="ID" column="UserId" type="guid">
          <generator class="guid" />
        </id>
    
        <discriminator column="ContactID" formula="(CASE WHEN ContactID IS NOT NULL THEN 1 ELSE 0 END)" />
    
        <property name="FirstName">
          <column name="FirstName" sql-type="nvarchar(500)" not-null="true" />
        </property>
    
        <property name="LastName">
          <column name="LastName" sql-type="nvarchar(500)" not-null="true" />
        </property>
    
        <subclass name="SiteContact" discriminator-value="1">
          <join table="Contact">
            <key column="ContactID" /> //I assume the problem is here. I have tried adding foreign-key="ContactID" to no success
    
            <property name="ExternalID" insert="false" update="false">
              <column name="ExternalID" sql-type="int" not-null="true" />
            </property>
    
            //The rest of the mapped columns
    
          </join>
          <join table="aspnet_Users">
            <key column="UserId" />
    
            <property name="ApplicationId">
              <column name="ApplicationId" sql-type="guid" not-null="true" />
            </property>
    
            <property name="UserName">
              <column name="UserName" sql-type="nvarchar(256)" not-null="true" />
            </property>
    
            <property name="LoweredUserName">
              <column name="LoweredUserName" sql-type="nvarchar(256)" not-null="true" />
            </property>
    
            <property name="MobileAlias">
              <column name="MobileAlias" sql-type="nvarchar(16)" not-null="false" />
            </property>
    
            <property name="IsAnonymous">
              <column name="IsAnonymous" sql-type="bit" not-null="true" />
            </property>
    
            <property name="LastActivityDate">
              <column name="LastActivityDate" sql-type="datetime" not-null="true" />
            </property>
    
          </join>
        </subclass>
    
        <subclass name="SiteUser" discriminator-value="0">
          <join table="aspnet_Users">
            <key column="UserId" />
    
            //blah blah blah
    
          </join>
        </subclass>
    
      </class>
    
    </hibernate-mapping>