NHibernate:CreateCriteria和Exists子句

cbp*_*cbp 12 nhibernate exists createcriteria

如何使用CreateCriteria编写以下SQL:

SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id)
Run Code Online (Sandbox Code Playgroud)

tol*_*sm7 28

以下是如何做到这一点:

var fooBars = Session.CreateCriteria<FooBar>()
        .Add(Restrictions.IsNotEmpty("Bazs")).List<FooBar>();
Run Code Online (Sandbox Code Playgroud)

...假设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>();
Run Code Online (Sandbox Code Playgroud)


Tre*_*vor 5

刚刚解决了相关问题并最终找到了解决方案,我想我会在这里分享答案:

假设您希望查询原始问题,并在子查询中附加条件:

SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id
              AND Quantity = 5)
Run Code Online (Sandbox Code Playgroud)

假设你有一个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>();
Run Code Online (Sandbox Code Playgroud)

我不是100%相信别名"this"的硬编码,这是别名NHibernate自动分配给查询中的根实体(表),但这是我发现引用密钥的唯一方法.子查询中的父查询表.


cbp*_*cbp 3

我弄清楚了如何使用 IsNotEmpty 表达式来做到这一点。这里使用 NHibernate Lambda 扩展:

Session.CreateCriteria<FooBar>()
    .Add(SqlExpression.IsNotEmpty<FooBar>(x => x.Bazes))
    .List<FooBar>();
Run Code Online (Sandbox Code Playgroud)