【问题标题】:NHibernate QueryOver Having clauseNHibernate QueryOver Have 子句
【发布时间】:2011-06-15 13:57:37
【问题描述】:

我想用 QueryOver 编写这样的查询,这样结果 SQL 将类似于以下内容:

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

我该怎么做?

【问题讨论】:

    标签: nhibernate queryover


    【解决方案1】:

    我想你只会使用 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));
    

    【讨论】:

    • 应该是Projections.GroupProperty(Projections.Property&lt;Foo&gt;(foo =&gt; foo.Bar))
    • 如果我们使用 Projections.Sum() 有什么区别?
    【解决方案2】:

    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 产生以下 invalid SQL(使用 where 而不是 have):

        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 是正确的。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-30
    相关资源
    最近更新 更多