NHibernate QueryOver Наличие предложения - PullRequest
5 голосов
/ 15 июня 2011

Я хочу написать такой запрос с помощью QueryOver, чтобы результат SQL был похож на следующее:

Select Bar, count(*) from Foo group by Bar having count(*) > 1

Как я могу это сделать?

Ответы [ 2 ]

7 голосов
/ 15 июня 2011

Я думаю, вы бы просто использовали метод Where

Session.QueryOver<Foo>()
    .Select(Projections.GroupProperty(Projections.Property<Foo>(foo => foo.Bar)),
            Projections.Count<Foo>(f => f.Id))
    .Where(Restrictions.Gt(Projections.Count<Foo>(f => f.Id), 1));
3 голосов
/ 28 марта 2012

Ответ от Вадима правильный, просто хочу упомянуть, что это может быть проблемой, если нужно проверить условие «наличие» в другом поле базы данных.

Например, следующий SQL:

select Foo.Bar, COUNT(*) from Foo
group by Foo.Bar
having Foo.Bar <> COUNT(*)

По сути, должен быть создан с помощью QueryOver:

Session.QueryOver<Foo>()
    .Select(Projections.GroupProperty(Projections.Property<Foo>(foo => foo.Bar)),
            Projections.Count<Foo>(f => f.Id))
    .Where(Restrictions.NotEqProperty(Projections.Count<Foo>(f => f.Id), Projections.Property<Foo>(foo => foo.Bar)));

НО, к сожалению, NHibernate создает следующие недействительные SQL (используя вместо вместо): 1011 *

    select Foo.Bar, COUNT(*) from Foo
    group by Foo.Bar
    where Foo.Bar <> COUNT(*)

Чтобы преодолеть эту проблему, мне пришлось создать следующее наследование:

    public class NonEqPropertyExpression : EqPropertyExpression
    {
        public NonEqPropertyExpression(IProjection lhsProjection, IProjection rhsProjection)
            : base(lhsProjection, rhsProjection)
        {
        }

        protected override string Op
        {
            get { return "<>"; }
        }
    }

и используйте мой новый класс вместо стандартного NonEqProperty:

Session.QueryOver<Foo>()
    .Select(Projections.GroupProperty(Projections.Property<Foo>(foo => foo.Bar)),
            Projections.Count<Foo>(f => f.Id))
    .Where(new NonEqPropertyExpression(Projections.Count<Foo>(f => f.Id), Projections.Property<Foo>(foo => foo.Bar)));

В этом случае полученный SQL правильный.

...