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

NHibernate-如何在返回超类时查询子类属性?,nhibernate,linq-to-nhibernate,Nhibernate,Linq To Nhibernate,使用NHibernate;在子类级别执行限制时,是否可以查询超类 例如(psuedo代码的命名): 我将如何执行以下查询: 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或criteria API呢 由于HQL和ICriteria是域查询工具,我发现很难期望有这样的功能

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

例如(psuedo代码的命名):

我将如何执行以下查询:

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或criteria API呢

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

唯一接近的方法是使用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

谢谢你;不幸的是,除了使用本机sql之外,没有更干净的方法。我想知道执行联合操作是否是更好的选择?
    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))))
        )