1

まず、テキストの壁について申し訳ありません。

私は次のスキーマを持っています。User_Contactにnullが含まれている可能性があることに注意してくださいContactID

スキーマ

クラスレベルでは、次のように実装されます

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

つまり、基本的には、すべてSiteContactがであるが、すべてがであるとはSiteUser限らないという考え方です。SiteUserSiteContact

私が完全に立ち往生しているのは、nHibernateでこの関係をマッピングする方法です。取得できるようですが、取得SiteUserできませんSiteContact。理由は明らかです。私が実装したマッピングにより、次のSQLが実行されます。

SELECT this_.userid             AS UserId18_0_, 
       this_.firstname          AS FirstName18_0_, 
       this_.lastname           AS LastName18_0_, 
       //Blah blah.....
FROM   user_contact this_ 
       INNER JOIN contact this_1_ 
               ON this_.userid = this_1_.contactid  //Here is the error this should be ContactID = ContactID
       INNER JOIN aspnet_users this_2_ 
               ON this_.userid = this_2_.userid 
WHERE  ( CASE 
           WHEN this_.contactid IS NOT NULL THEN 1 
           ELSE 0 
         END ) = '1' 

しかし、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>

うまくいけば、誰かが私がこのマッピングについて正しい方向に進んでいるかどうかを教えてくれ、おそらくいくつかのガイダンスを提供できますか?

4

1 に答える 1

1

これは、かなり複雑なマッピング方法のようです。この状況で継承を使用することでどのようなメリットが得られるかわかりません。代わりに、コンポジションを使用することをお勧めします(つまり、テーブルごとにクラスを作成し、関係をマッピングします)。

そうは言っても、あなたにはおそらくあなたの理由があるので、私があなたが望むと思うことを達成するために、次のことを提案します:

  1. SiteUserクラスを基本クラスとしてマップし、User_Contactからaspnet_Usersへの結合を使用します(したがって、マッピングのベースとしてUserを使用しないでください)
  2. 次に、サブクラスの代わりに結合サブクラスマッピングを使用して、SiteContactをサブクラスとしてマップします。これにより、識別子を使用する必要がなくなります。
于 2012-09-14T13:13:24.383 に答える