2

次のデータモデルがあります。

Category
  Date
  Products

Product
  Date
  Payments

Payment
  Date

NHibernate を使用してツリー全体を熱心にロードしたいと考えています。私はそれを次のようにすることを考えました:

var query = from cat in session.Query<Category>() select cat;     
query = query.FetchMany(c => c.Products).ThenFetch(c=>c.Payments);     
var result = query.Distinct().ToList();

これはうまくいきます。左外部結合を作成し、結果を返します。

しかし、2012 年 1 月 1 日よりも新しいエンティティのみを取得したいと考えています。そこで、DateFilter というフィルターを作成し、Category、Product、および Payment マッピングに以下を追加しました。

ApplyFilter<DateFilter>();

フィルターを有効にしたとき、生成された SQL クエリの "WHERE" 句に、Category、Product、および Payment テーブルのフィルター条件があると予想していましたが、Category (最上位要素) の条件しかありませんでした。

コード:

using (var session = SessionProvider.OpenSession(ConnectionString))
{
    session.EnableFilter("DateFilter")
        .SetParameter("start", OracleHelper.ToDate(new DateTime(2012, 1, 1)));

    var query = from cat in session.Query<Category>() select cat;     
    query = query.FetchMany(c => c.Products).ThenFetch(c=>c.Payments);     
    var result = query.Distinct().ToList();
}

生成された SQL:

SELECT ... FROM   ... WHERE category_.Date >= '2012-01-01'

そして、私が期待したのは:

SELECT ... FROM   ... WHERE category_.Date >= '2012-01-01' 
    and product_.Date >= '2012-01-01'
    and payment_.Date >= '2012-01-01'

また、次のようにマッピングにフィルターを適用してみました。

HasMany<Payment>(x => x.Payments).ApplyFilter<DateFilter>();

ただし、「WHERE」句ではなく、結合にフィルターを適用します (フィルター条件を結合の ON 句に入れます)。これにより、左外部結合を使用して間違った結果が得られます。

フィルターは最上位のエンティティにのみ適用でき、熱心にフェッチされた子エンティティには適用できませんか?

やりたいことを他にどのように達成できますか?

ありがとう!

4

0 に答える 0