Выполнение запроса или с подзапросом

#nhibernate #queryover

#nhibernate #выполнение запроса

Вопрос:

У меня есть следующий запрос NHibernate с использованием подзапроса:

 NHContext.Session.QueryOver<Item>()
            .WithSubquery.WhereProperty(x => x.ItemId).In(QueryOver.Of<Foo>().Where(x => x.AFlag).Select(x => x.ItemId))
            .WithSubquery.WhereProperty(x => x.ItemId).In(QueryOver.Of<Bar>().Where(x => x.AFlag).Select(x => x.Item))  
            .Future<Item>();
  

При этом выполняется следующий SQL:

 SELECT *
FROM   item this_
WHERE  this_.ItemId in (SELECT this_0_.ItemId as y0_
                            FROM   Foo this_0_
                            WHERE  this_0_.AFlag = 1 /* @p0 */)
and    this_.ItemId in (SELECT this_0_.ItemId as y0_
                            FROM   Bar this_0_
                            WHERE  this_0_.AFlag = 1 /* @p0 */)
  

Я бы хотел, чтобы он использовал ИЛИ так, например:

 SELECT *
FROM   item this_
WHERE  this_.ItemId in (SELECT this_0_.ItemId as y0_
                            FROM   Foo this_0_
                            WHERE  this_0_.AFlag = 1 /* @p0 */)
or   this_.ItemId in (SELECT this_0_.ItemId as y0_
                            FROM   Bar this_0_
                            WHERE  this_0_.AFlag = 1 /* @p0 */)
  

Я знаю, что могу сделать это в критериях, выполнив что-то вроде:

 var disjunction = new Disjunction();
disjunction.Add(Subqueries.PropertyIn("ItemId", 
     DetachedCriteria.For<Foo>()
     .SetProjection(Projections.Property("ItemId"))
     .Add(Restrictions.Eq("AFlag", 1))
));
  

Но было интересно, есть ли более простой способ сделать это с помощью QueryOver и избежать использования строк для имен свойств.

Спасибо за любую помощь.

Ответ №1:

Для менее распространенной дизъюнкции (или), я думаю, вам нужно использовать Subqueries.WhereProperty<> вместо WithSubquery

 Session.QueryOver<Item>()
    .Where(Restrictions.Disjunction()
        .Add(Subqueries.WhereProperty<Item>(x => x.ItemId).In(QueryOver.Of<Foo>().Where(x => x.AFlag).Select(x => x.ItemId)))
        .Add(Subqueries.WhereProperty<Item>(x => x.ItemId).In(QueryOver.Of<Bar>().Where(x => x.AFlag).Select(x => x.Item))))
    .Future<Item>();