Question

How would I express the following in terms of a fluent nhibernate syntax for a fetchplan

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

The best I can manage is this but it doesn't even compile.

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);
Was it helpful?

Solution

The QueryOver syntax should be like this:

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
    ;

And now query.List<Person>().SingleOrDefault() should return Male or Staff guy.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top