0

自動マッピングで Fluent Nhibernate を使用していますが、現在の継承のために双方向の HasMany 関係を設定する際に問題があります。

私のコードの単純化されたバージョンは次のようになります

public abstract class BaseClass
{
    public BaseClass Parent { get; set; }
}

public class ClassA : BaseClass
{
    public IList<ClassB> BChilds { get; protected set; }
    public IList<ClassC> CChilds { get; protected set; }
}

public class ClassB : BaseClass
{
    public IList<ClassD> DChilds { get; protected set; }
}

public class ClassC : BaseClass
{
}

public class ClassD : BaseClass
{
}

すべてのクラスは 1 つの親を持つことができ、一部の親は 2 つのタイプの子を持つことができます。テーブルになるタイプごとのテーブル継承を使用しています

  • 「ベースクラス」
  • 「クラスA」
  • 「クラスB」
  • 「クラスC」
  • 「クラスD」

機能する双方向マッピングを取得するために、次のオーバーライドを行いました (ClassA の 1 つの例)。

mapping.HasMany<BaseType>(x => x.BChilds).KeyColumn("Parent_Id");
mapping.HasMany<BaseType>(x => x.CChilds).KeyColumn("Parent_Id");

これは、子の型が 1 つしかないクラスでは正常に機能しますが、子の型が 2 つある ClassA は、各リストで BaseType のすべてのサブタイプを取得し、もちろん例外になります。私は2つの異なる回避策を見てきましたが、どれも本当に十分ではないと感じており、それを解決するためのより良い方法があると本当に信じています.

回避策 1: HasMany マッピングで具体的なサブタイプを指定します。(より多くの情報で更新)

mapping.HasMany<ClassB>(x => x.BChilds).KeyColumns("Parent_Id"); 

(BaseType を ClassB に置き換え)

このマッピングにより、NHibernate は場合によっては ClassB テーブルで Parent_Id という名前の列を探しますが、明らかに BaseClass テーブルに属しているため、そのような列はありません。この問題は、ClassA 選択時に BChilds に基づくステートメントを追加した場合にのみ発生します。たとえば、ClassA のエンティティをロードしてから ClassA.BChilds を呼び出すと動作するように見えますが、(NhibernateLinq を使用して) 次のようなクエリを実行します。

Query<ClassA>().Where(c => c.BChilds.Count == 0) 

間違ったテーブルが使用されます。したがって、このテーブルに同じ名前の新しい列を手動で作成し、すべての値をコピーする必要があります。機能しますが、リスクが高く、柔軟性がまったくありません。

回避策 2:具象型を示す BaseClass に列を追加し、HasMany マッピングに where ステートメントを追加します。

(回避策1への更新後、これが実行可能な解決策になるかどうかわかりません)

列を追加することで、discriminatorValue で階層ごとのテーブル継承を使用する場合と同じ方法で実行できます。つまり、BaseType テーブルは ClassA、ClassB の値を持つ新しい列を取得します... NHibernate が継承全体をどれだけ適切に処理しているかを考えると、NHibernate のマニュアルを読むことで、型ごとのテーブルにディスクリミネーターは必要ないと思いますシナリオでは、Nhibernate はすでに難しい部分を行っているようで、新しい列を追加せずにクリーンな方法でこれを処理できるはずですが、方法がわかりません。

4

1 に答える 1

0

基本クラスのマッピングと、サブクラスのマップはどのように見えますか? あなたはできるはずです

mapping.HasMany(x => x.BChilds);

そして、正しいマッピングがあれば、問題はないはずです。それが流暢な冬眠している場合は、調べてください

UseUnionSubclassForInheritanceMapping();
于 2013-05-26T11:30:45.480 に答える