【问题标题】:Multiple conditions in HAVING clause with NHibernate Criteria?带有NHibernate Criteria的HAVING子句中的多个条件?
【发布时间】:2012-10-17 04:37:58
【问题描述】:

我正在尝试使用 NHibernate 的 Criteria API 来编写与此等效的代码:

select foo_id from foo_history
group by foo_id
having sum(bar_in) > 0 or sum(baz_in) > 0;

使用此映射:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="MVC"
                   namespace="MVC.Model.Things">
  <class name="MVC.Model.Things.FooHistory, MVC"
         table="foo_history">
    <id name="ID" column="foo_hist_id" type="guid"
        unsaved-value="00000000-0000-0000-0000-000000000000">
      <generator class="guid.comb" />
    </id>

    <!-- Properties -->
    <property name="BarIn" column="bar_in" type="decimal"
              precision="19" scale="4" not-null="true" />
    <property name="BazIn" column="baz_in" type="decimal"
              precision="19" scale="4" not-null="false" />

    <!-- Foreign Keys -->
    <many-to-one name="Foo" column="foo_id"
                 class="MVC.Model.Things.Foo, MVC.Model.Things"
                 not-null="true" />
  </class>
</hibernate-mapping>

还有这个 Criteria 代码(已分离,因为它将是一个子查询):

var results = DetachedCriteria.For<FooHistory>("fh")
    .SetProjection(Projections.ProjectionList()
        .Add(Projections.GroupProperty(Projections.Id()))
        .Add(Projections.Sum("fh.BarIn"))
        .Add(Projections.Sum("fh.BazIn")))
    .Add(Restrictions.Gt(Projections.Sum("fh.BarIn"), 0) ||
        Restrictions.Gt(Projections.Sum("fh.BazIn"), 0))
    .GetExecutableCriteria(session).List();

问题是在SetProjection()之后添加条件限制会导致NHibernate生成无效的MySQL:

SELECT this_.foo_hist_id as y0_,
       sum(this_.bar_in) as y1_,
       sum(this_.baz_in) as y2_
FROM foo_history this_
WHERE (sum(this_.bar_in) > ?p0
       or sum(this_.baz_in) > ?p1)
GROUP BY this_.foo_hist_id

...使用 WHERE 而不是 HAVING。使用单个限制可以正常工作,并且一切都是正确的。我假设由于 HN-1280(“向 CreateCriteria 查询添加 HAVING 支持,修复参数顺序错误”)这是可能的,但我没有使用正确的“OR”语言(例如,Restrictions.Disjunction() 总是创建 WHERE)。

这可能吗?

【问题讨论】:

标签: c# mysql nhibernate nhibernate-criteria having-clause


【解决方案1】:

我遇到了这个问题,但是我认为我的解决方法不是很好,因为它不起作用,例如当您需要 ToRowCountQuery() 进行分页时。但无论如何……你可以使用这个类来代替内置的 OrExpression

class OrHaving : OrExpression
    {
        public OrHaving(ICriterion lhs, ICriterion rhs) : base(lhs, rhs)
        {
        }

        public override IProjection[] GetProjections()
        {
            return LeftHandSide.GetProjections().Concat(RightHandSide.GetProjections()).ToArray();
        }
    }

喜欢

.Add(new OrHaving (Restrictions.Gt(Projections.Sum("fh.BarIn"), 0) ,
                   Restrictions.Gt(Projections.Sum("fh.BazIn"), 0)))

【讨论】:

  • 谢谢先生,非常感谢您的回答。从我尝试过的所有不同答案和方法中,这是唯一对我有用的答案。 (我也继承了 AndExpression,它就像一个魅力)
猜你喜欢
  • 1970-01-01
  • 2010-12-20
  • 1970-01-01
  • 2012-09-15
  • 2010-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-26
相关资源
最近更新 更多