5

結果のSQLが次のようになるように、QueryOverを使用してこのようなクエリを記述したいと思います。

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

どうすればいいですか?

4

2 に答える 2

7

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));
于 2011-06-15T14:24:38.460 に答える
3

Vadimからの答えは正しいです。別のデータベースフィールドに対して「持っている」状態をチェックする必要がある場合、それは挑戦になる可能性があることを述べたいと思います。

たとえば、次の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を生成します(持つ代わりにwhereを使用):

    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は正しいです。

于 2012-03-27T21:20:25.960 に答える