将SQL转换为Fetchplan的NHibernate Fluent语法

时间:2014-04-16 14:30:58

标签: c# nhibernate queryover

如何根据fetchplan的流利nhibernate语法表达以下内容

select *
from Person a
where 
(
 (Male = 0) or
 ((Male = 1) and exists (select * from Staff where PersonId = XXX and EmployeeId = YYY))
)
and PersonId = XXX

我能管理的最好的就是这个,但它甚至都没有编译。

Person pers = null;
Staff s = null;

var subquery = QueryOver.Of<Staff>(() => s)
                        .Where(() => s.Employee.Id == YYY)
                        .And(() => s.Person.Id == XXX);

var query = session.QueryOver<Person>()
                   .Where(NHibernate.Criterion.Restrictions.Disjunction()
                   .Add(Subqueries.WhereProperty<Person>(a => !a.Male))
                   .Add(Subqueries.WhereProperty<Person>(a => a.Male))
                   .Add(Subqueries.WhereExists(subquery)))
                   .Where(() => pers.Id == XXX);

1 个答案:

答案 0 :(得分:1)

QueryOver语法应如下所示:

Person pers = null;
Staff s = null;

var subquery = QueryOver
    .Of<Staff>(() => s)
    .Where(() => s.Employee.Id == YYY)
    .And(() => s.Person.Id == XXX)
    // any SELECT clause, including the sub select, must return something
    .Select(sub => sub.Id)
    ;

var query = session
    // let's use alias we've already declared above
    .QueryOver<Person>(() => pers)

    // the first condition
    .Where(

        // let's simplify the stuff 
        // instead of:   (IsMale OR (!IsMale AND exists)
        // use the same: (IsMale OR exists)

        Restrictions.Disjunction()
            .Add(() => pers.Male)  // alias pers
            .Add(Subqueries.Exists(subquery.DetachedCriteria))
    )
    // the second top level condition
    .And(() => pers.ID == XXX) // alias pers
    ;

现在query.List<Person>().SingleOrDefault()应该返回男性或员工。