1

私は、膨大な数の列を持つ ScheduledJobs と呼ばれる DB テーブルと、膨大なプロパティを持つ単一の一致する C# オブジェクトに遭遇しました。私はそのデザインに満足しておらず、サブクラスごとのテーブル戦略を使用して分割したいと考えていました。それ以外の

public class ScheduledJobs
{
    public int ID { get; set; } // always needed
    public int JobTypeID { get; set; } // always needed to distinguish A from B
    public int Foo { get; set; } // needed by Job A
    public int Bar { get; set; } // needed by Job B
}

私は持っている

public abstract class ScheduledJob
{
    public int ID { get; set; }
    public ScheduledJobType JobType { get; set; }
}

public class ScheduledJobA : ScheduledJob
{
    public int Foo { get; set; }
}

public class ScheduledJobB : ScheduledJob
{
    public int Bar { get; set; }
}

NHibernate .hbm.xml ファイルを書き直して (Fluent ではなく、申し訳ありません)、以下を使用しました。

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
    <class name="ScheduledJob" table="ScheduledJobs" abstract="true" lazy="false">
        <id name="ID" column="ID" type="Int32" unsaved-value="0">
            <generator class="identity" />
        </id>
        <many-to-one name="ScheduledJobType" column="JobTypeID" class="ScheduledJobType" />

        <joined-subclass name="ScheduledJobA" table="ScheduledJobsA" lazy="false">
            <key column="JobID" />
            <property name="Foo" type="Int32" />
        </joined-subclass>

        <joined-subclass name="ScheduledJobB" table="ScheduledJobsB" lazy="false">
            <key column="JobID" />
            <property name="Bar" type="Int32" />
        </joined-subclass>
    </class>
</hibernate-mapping>

すごい!私の問題は、サブクラス化されたジョブを賢く取得する方法がわからないことです。1 つの大きなテーブルの利点は、型やキャストについて心配する必要がないことです。

ScheduledJob job = Repository.ScheduledJob.Get(id);

私のセットアップでは、同じ ID を持っています (これで十分なはずです。まだ一意です)。ただし、型は不明です。抽象ジョブをフェッチし、JobTypeID を調べ、関連する C# サブクラスを見つけて、その下で再フェッチする必要があります。サブクラス。

必要に応じて、JobTypeID を取り込むことができます。その ID を、それに関連付けられているジョブ サブクラス テーブルとペアにする必要があります。

要するに、NHibernate から受け取った ScheduledJob オブジェクトを正しいサブクラスにする必要があり、私の介入は可能な限り少なくする必要があります。ここでディスクリミネータを使用できることは素晴らしいことですが、公式ドキュメントでは許可されていません。このデザインは、根本的に何かを誤解しているように感じさせます。私を正しい方向に向けてください。

ありがとう!

4

1 に答える 1

1

私のセットアップでは、同じ ID を持っています (これで十分なはずです。まだ一意です)。ただし、型は不明です。抽象ジョブをフェッチし、JobTypeID を調べ、関連する C# サブクラスを見つけて、その下で再フェッチする必要があります。サブクラス。

実際には、 を調べたりJobTypeID、再度取得したりする必要はありません。それが NHibernate の仕事です。最初のフェッチで、適切な派生型を決定し、この型のオブジェクトを自動的にインスタンス化します。

オブジェクトがフェッチされた後に型を照会する必要がある場合は、C# の型チェックとキャストを使用できます。

ScheduledJob job = Repository.ScheduledJob.Get(id);
if (job is ScheduledJobA)
{
      ScheduledJobA jobA = (ScheduledJobA)jobA;
      ProcessJobA(jobA);
}
else if (job is ScheduledJobB)
{
      ScheduledJobB jobB = (ScheduledJobB)jobB;
      ProcessJobB(jobB);
}
于 2014-09-11T06:24:26.657 に答える