NHibernate - 如何在返回超类时查询子类属性?

时间:2010-07-28 23:57:05

标签: nhibernate linq-to-nhibernate

使用NHibernate;是否可以在子类级别执行限制时查询超类?

例如(psuedo-code的appologies):

Class A
   Property Prop1
End Class

Class B
   Inherits Class A
   Property Prop2
End Class

Class C
   Inherits Class A
   Property Prop3
End Class

我如何执行如下查询:

from A where Prop1 = 'foo' AND 
((if A is B) then B.Prop2 = 'bar' OR
 (if A is C) then C.Prop3 = 'bar')

使用Nhibernate.Linq是否可以这样?那么hql还是标准API怎么样?

1 个答案:

答案 0 :(得分:3)

由于HQL和ICriteria是域查询工具,我发现很难期待这样的功能。

AFAIK唯一的关键是使用ICriteria的Expression.Sql(),您可以在其中查询超类,但是使用纯sql注入子类特定的片段。在那里,表达式就像

crit.Add(
  Expression.Sql(@"(({alias}.DiscrimCol = :subClassADiscrimVal AND {alias}.Col2 = :barVal) 
    OR ({alias}.DiscrimCol = :subClassBDiscrimVal AND {alias}.Col3 = :barVal))", 
    new object[] { "subA", "subB", "bar" }, 
    new IType[] { NHibernateUtil.String,NHibernateUtil.String,NHibernateUtil.String } )
);

不好但是有效

另一种方法是使用ISQLQuery,它至少允许SELECT部分​​是特定于域的(并使用.AddEntity()),因此您仍然可以选择托管超类,而WHERE部分包含特定的子类片段

=========更新==========

再想一想,有一种方法可以通过HQL或ICriteria实现这一点,但它更多的是一种解决方法,并且性能较差,因为它涉及子查询。 ICriteria的例子:

    nhSes.CreateCriteria(typeof(Super))
        .Add(
            Restrictions.Disjunction()
                .Add(Subqueries.PropertyIn("Id", DetachedCriteria.For(typeof(ChildA))
                                                    .SetProjection(Projections.Id())
                                                    .Add(Restrictions.Eq("ChildAProp", barVal))))
                .Add(Subqueries.PropertyIn("Id", DetachedCriteria.For(typeof(ChildB))
                                                    .SetProjection(Projections.Id())
                                                    .Add(Restrictions.Eq("ChildBProp", barVal))))
        )

我正在查询每个孩子,调整其id,然后选择超类,用投影的子ID限制IN的ID。