NHibernate:Subqueries.Exists不工作

时间:2010-03-05 01:31:38

标签: nhibernate

我正在尝试使用NHibernate的标准api获取如下的sql:

SELECT * FROM Foo
   WHERE EXISTS (SELECT 1 FROM Bar 
                 WHERE Bar.FooId = Foo.Id
                 AND EXISTS (SELECT 1 FROM Baz
                            WHERE Baz.BarId = Bar.Id)

所以基本上,Foos有很多酒吧和酒吧有很多Bazes。我想得到所有有Bazes酒吧的Foos。

要做到这一点,分离标准似乎最好,如下所示:

var subquery = DetachedCriteria.For<Bar>("bar")
    .SetProjection(Projections.Property("bar.Id"))
    .Add(Restrictions.Eq("bar.FooId","foo.Id")) // I have also tried replacing "bar.FooId" with "bar.Foo.Id"
    .Add(Restrictions.IsNotEmpty("bar.Bazes"));

return Session.CreateCriteria<Foo>("foo")
     .Add(Subqueries.Exists(subquery))
     .List<Foo>();

但是这引发了异常: System.ArgumentException:找不到匹配的条件信息提供者:bar.FooId = foo.Id和bar.Bazes不为空

这是NHibernate的错误吗?有更好的方法吗?

2 个答案:

答案 0 :(得分:3)

尝试在子查询的Bar类中创建Foo路径上的条件或别名,然后应用eaual限制。

var subquery = DetachedCriteria.For<Bar>("bar")
    .SetProjection(Projections.Property("bar.Id"))
    .Add(Restrictions.IsNotEmpty("bar.Bazes"))
    .CreateCriteria("Foo")
         .Add(Restrictions.Eq("bar.FooId","Id"));

或CreateAlias(“Foo”,“foo”)

var subquery = DetachedCriteria.For<Bar>("bar")
    .SetProjection(Projections.Property("bar.Id"))
    .Add(Restrictions.IsNotEmpty("bar.Bazes"))
    .CreateAlias("Foo","foo")
    .Add(Restrictions.Eq("bar.FooId","foo.Id"));

答案 1 :(得分:2)

我刚刚解决了我遇到的同样问题。

我的解决方案是将'child'实体的外键(指向父实体)与'Mapped Reference属性'限定为该父项。

此外,由于你的'childEntity.FK = parentEntity.Key'实际上是将属性等同于你想要使用Expression.EqProperty(..,..)而不是Expression.Eq(..,..)的属性

所以,我建议改变这一行:

Add(Restrictions.Eq("bar.FooId","foo.Id")) 

对此:

.Add(Restrictions.EqProperty("bar.Foo.Id","foo.Id"))