6

まず、はい、私は DistinctRootEntityResultTransformer を使用しています。

次の(Fluent NHibernate)マッピングがあります:

public FirstObjectMap() 
{
    Id(x => x.Id):
    HasMany<SecondObject>(x => x.SecondItems).KeyColumn("FirstObject_ID");
}

public SecondObjectMap()
{
    Id(x => x.Id).Column("ID");
    References(x => x.ThirdObject).Column("ThirdObject_ID");
}

public ThirdObjectMap()
{
    Id(x => x.Id).Column("ID");
    HasMany<D>(x => x.FourthItems).KeyColumn("ThirdObject_ID");
}

public FourthObjectMap()
{
    Id(x => x.Id).Column("ID");
}

SecondObject は ThirdObject を参照していることに注意してください (キーが SecondObject 上にあることを意味します)。

私のクエリは次のようになります。

var query = session.CreateQuery("select distinct first from " + 
   "FirstObject as first " +
   "left join fetch first.SecondItems as second " +
   "left join fetch second.ThirdObject as third " + 
   "left join fetch third.FourthItems as four where ...");

// This is not even needed as I'm using distinct in HQL
query.SetResultTransformer(new DistinctRootEntityResultTransformer());

var results = query.List<ReinsurableObject>();

テスト用に、データベースに 1 つの FirstObject、1 つの SecondObject、1 つの ThirdObject、および 24 の FourthObject があります。SQL クエリは、調べたとおり 24 行を返します。

ただし、キャッチは次のとおりです。NHibernate は以下を作成します。

1 FirstObject
  24 SecondObject (should be 1)
     24 x 1 ThirdObject (should be 1)
         24 x 1 x 24 FourthObject (should be 24)

したがって、何らかの理由で NH は 1 ではなく 24 の SecondObject を作成します。

「結合フェッチ」(左または内部は問題ではないようです) を参照 (SecondObject の ThirdObject への参照) にマップする方法がわからないのではないかと思います。

私のオプションは何ですか?データ モデルを変更することはできませんが、すべてを熱心に読み込む必要があります。

前もって感謝します!

4

1 に答える 1

4

個別のルート エンティティは、親と子をロードする場合にのみ機能します。孫とひ孫の場合、これは機能しません。問題は、複数のコレクションの関連付けを読み込んでいて、大きなcartesian product

Ayende によるこの記事を読んで、これが当てはまる理由と回避策を説明してください。

すぐに明らかにならないものは、デカルト積になります。これはドキュメントで指摘されていますが、この動作には理由があるかもしれませんが、理想とはほど遠いことに誰もが同意できると思います.

于 2012-04-25T17:05:05.413 に答える