Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NHibernate QueryOver with subquery or other ideas how this can work?

I have following queries:

Model.RampActiveHour rah = null;

var defaultWeekQuery = QueryOver.Of<Model.RampAdditionalDefaultWeek>()
                                   .Where(adw => adw.Ramp == rah.Ramp && 
                                          adw.Active && adw.FromDate <= date &&
                                          adw.ToDate >= date)
                                   .Select(adw => adw.ID).Take(1);
var result = session.QueryOver(() => rah)
                .Where(ah => ah.DayOfWeek == date.DayOfWeek)
                .WhereRestrictionOn(ah => ah.Ramp).IsIn((ICollection) ramps)
                .WithSubquery.WhereProperty(ah=>ah.AdditionalDefaultWeek)
                    .Eq(defaultWeekQuery)
                .List();

The result query is:

SELECT
 this_.ID as ID3_0_,
 this_.DayOfWeek as DayOfWeek3_0_,
 this_.Active as Active3_0_,
 this_.SlotsCount as SlotsCount3_0_,
 this_.SlotId as SlotId3_0_,
 this_.SlotLength as SlotLength3_0_,
 this_.Date as Date3_0_,
 this_.ramp_id as ramp8_3_0_,
 this_.additional_default_week_id as additional9_3_0_,
 this_.Previous as Previous3_0_,
 this_.Next as Next3_0_ 
FROM RampActiveHour this_ 
WHERE this_.DayOfWeek = 3 /* ?p0 */ and
 this_.ramp_id in (
    3484 /* ?p1 */,
     3498 /* ?p2 */)
 and
     this_.additional_default_week_id = (
        SELECT
             this_0_.ID as y0_ 
        FROM RampAdditionalDefaultWeek this_0_ 
        WHERE (
            (
                (
                    this_0_.ramp_id = this_.ramp_id and
                         this_0_.Active = 1 /* ?p103 */)
                     and
                         this_0_.FromDate <= '2011-07-20T00:00:00.00' /* ?p104 */)
                     and
                         this_0_.ToDate >= '2011-07-20T00:00:00.00' /* ?p105 */)
                     limit 1 /* ?p106 */)

The query is correct. The problem is that in my model I have a property in RampActiveHour called AdditionalDefaultWeek and this property is mapped to the RampAdditionalDefaultWeek table with many-to-one. This many to one relation can be null (which means that there is not additional default week) or can be set to an int (which mean there is active additional default week).

The problem is that if there is no active AdditionalDefaultWeek the subquery returns empty set and for this reason the whole query return empty set.

I was thought about Projections.Conditional projections, but still can make this work.

Any help is much appreciated.

Thanks.

like image 581
Nikola Yankov Avatar asked Jan 19 '23 04:01

Nikola Yankov


1 Answers

var result = session.QueryOver(() => rah)
            .Where(ah => ah.DayOfWeek == date.DayOfWeek)
            .WhereRestrictionOn(ah => ah.Ramp).IsIn((ICollection) ramps)
            .WithSubquery.WhereProperty(ah=>ah.AdditionalDefaultWeek).Eq(defaultWeekQuery)
            .Where(new Disjunction()
                .Add(Subqueries.WhereProperty(ah=>ah.AdditionalDefaultWeek).Eq(defaultWeekQuery))
                .Add(new Conjunction()
                    .Add(Subqueries.WhereNotExists(defaultWeekQuery))
                    .Add(Restrictions.Where(ah=>ah.AdditionalDefaultWeek == null)))
            .List();

I'm not so fluent in query over, so there might be a better syntax

like image 87
Firo Avatar answered Apr 26 '23 12:04

Firo