QueryOver Или с подзапросом - PullRequest
       3

QueryOver Или с подзапросом

23 голосов
/ 31 октября 2011

I У меня был следующий запрос 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 */)

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

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

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

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

1 Ответ

37 голосов
/ 01 ноября 2011

Для менее распространенного дизъюнкции (или), я думаю, вам нужно использовать 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>();
...