CreateCriteriaを使用して次のSQLを作成するにはどうすればよいですか。
SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id)
CreateCriteriaを使用して次のSQLを作成するにはどうすればよいですか。
SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id)
これを行う方法は次のとおりです。
var fooBars = Session.CreateCriteria<FooBar>()
.Add(Restrictions.IsNotEmpty("Bazs")).List<FooBar>();
... FooBar オブジェクトにコレクション プロパティ (1 対多) "Bazs" があるとします。
別の方法として、次のような切り離された基準を使用することもできます。
DetachedCriteria dCriteria = DetachedCriteria.For<Baz>("baz")
.SetProjection(Projections.Property("baz.FooBarId"))
.Add(Restrictions.EqProperty("baz.FooBarId", "fooBar.Id"));
var fooBars = Session.CreateCriteria<FooBar>("fooBar")
.Add(Subqueries.Exists(dCriteria)).List<FooBar>();
関連する問題を解決したばかりで、最終的に解決策にたどり着いたので、ここで答えを共有したいと思いました。
サブクエリに追加の条件を付けて、元の質問クエリが必要であると仮定します。
SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id
AND Quantity = 5)
Baz クラスに、たとえば FooBarRef [Fluent Map クラスでは References() メソッドを使用する] という名前の親への参照があると仮定すると、次のようにクエリを作成します。
DetachedCriteria dCriteria = DetachedCriteria.For<Baz>("baz")
.SetProjection(Projections.Property("baz.FooBarId"))
.Add(Expression.EqProperty("this.FooBarId", "FooBarRef.Id"))
.Add(Expression.Eq("baz.Quantity", 5));
var fooBars = Session.CreateCriteria<FooBar>("fooBar")
.Add(Subqueries.Exists(dCriteria)).List<FooBar>();
クエリで NHibernate が自動的にルート エンティティ (テーブル) に割り当てるエイリアス "this" のハード コーディングについて、100% 確信はありませんが、サブクエリ内からの親クエリのテーブル。
IsNotEmpty式を使用してこれを行う方法を考え出しました。ここでは、NHibernateLambdaExtensionsを使用しています。
Session.CreateCriteria<FooBar>()
.Add(SqlExpression.IsNotEmpty<FooBar>(x => x.Bazes))
.List<FooBar>();