Question

I am having trouble converting the following to Sql to nhibernate:

SELECT DISTINCT Booking.*
FROM   Booking WHERE  Booking.Status = 2
            OR EXISTS (SELECT 1
            FROM   JourneyFuture
            WHERE  JourneyFuture.BookingId = Booking.BookingId
                    AND ((JourneyFuture.[IsDriverAssigned] = 0
                        AND JourneyFuture.[Status] = 1) -- live
                        OR JourneyFuture.[Status] = 2
                        OR JourneyFuture.[Status] = 4
                        OR (JourneyFuture.[Status] = 1
                            AND (JourneyFuture.IsMetricCalculated = 0
                                    OR JourneyFuture.Duration = 0
                                    OR JourneyFuture.Distance = 0))))

Here is what I have so far with Nhibernate:

Booking bookingAlias = null;    
var journeyFuture = QueryOver.Of<JourneyFuture>().Where(x=> x.Booking.Id==bookingAlias.Id).
                    And(x => (!x.IsDriverAssigned && x.Status==JourneyStatusType.Live) || x.Status==JourneyStatusType.CancelRequested
                                || x.Status == JourneyStatusType.Modified || 
                                (x.Status == JourneyStatusType.Live && (!x.IsMetricCalculated || x.Duration==0 || x.Distance==0)))
                                .Select(x=> x.Booking);

                var result = session.QueryOver<Booking>(() => bookingAlias)
                    .Where(x => x.Status == BookingStatusType.CancelRequested)
                    .WithSubquery.WhereExists(journeyFuture)
                    .List<Booking>();

This however is producing an "And" exists which makes sense, but how do I get an OR EXISTS?

Any help appreciated.

Was it helpful?

Solution

The following should work:

Booking bookingAlias = null;    
var journeyFuture = QueryOver.Of<JourneyFuture>().Where(x=> x.Booking.Id==bookingAlias.Id).
    And(x => (!x.IsDriverAssigned && x.Status==JourneyStatusType.Live) || x.Status==JourneyStatusType.CancelRequested
                || x.Status == JourneyStatusType.Modified || 
                (x.Status == JourneyStatusType.Live && (!x.IsMetricCalculated || x.Duration==0 || x.Distance==0)))
                .Select(x=> x.Booking);

var result = session.QueryOver<Booking>(() => bookingAlias)
    .Where(
        Restrictions.Or(
            Restrictions.Where(() => bookingAlias.Status == BookingStatusType.CancelRequested),
            Subqueries.Exists(journeyFuture.DetachedCriteria)))
    .List<Booking>();

Basically replace .WithSubquery with the more powerful Restrictions.Or and Subqueries.Exists. I wish there was a way to do this with .WithSubquery, but I'm not sure there is.

In general, with complex restrictions, you can dip down into the Restrictions class. The downside to this is that it usually makes your code more complex.

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