次のデータモデルがあります。
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 句に入れます)。これにより、左外部結合を使用して間違った結果が得られます。
フィルターは最上位のエンティティにのみ適用でき、熱心にフェッチされた子エンティティには適用できませんか?
やりたいことを他にどのように達成できますか?
ありがとう!