如何使用CreateCriteria编写以下SQL:
SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id)
答案 0 :(得分:28)
以下是如何做到这一点:
var fooBars = Session.CreateCriteria<FooBar>()
.Add(Restrictions.IsNotEmpty("Bazs")).List<FooBar>();
...假设FooBar对象中有一个集合属性(一对多)“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>();
答案 1 :(得分:5)
刚刚解决了相关问题并最终找到了解决方案,我想我会在这里分享答案:
假设您想要查询原始问题,并在子查询中附加条件:
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>();
我不是100%相信别名“this”的硬编码,这是别名NHibernate自动分配给查询中的根实体(表),但这是我发现引用它的唯一方法子查询中父查询表的键。
答案 2 :(得分:3)
我使用IsNotEmpty表达式计算了如何执行此操作。这里使用的是NHibernate Lambda Extensions:
Session.CreateCriteria<FooBar>()
.Add(SqlExpression.IsNotEmpty<FooBar>(x => x.Bazes))
.List<FooBar>();