wes*_*wes 5 c# mysql nhibernate nhibernate-criteria having-clause
我正在尝试使用NHibernate的Criteria API来编写相当于这个:
select foo_id from foo_history
group by foo_id
having sum(bar_in) > 0 or sum(baz_in) > 0;
Run Code Online (Sandbox Code Playgroud)
使用此映射:
<?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>
Run Code Online (Sandbox Code Playgroud)
和这个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();
Run Code Online (Sandbox Code Playgroud)
问题是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
Run Code Online (Sandbox Code Playgroud)
...使用WHERE而不是HAVING.使用单个限制工作正常,一切都是正确的.我假设自从HN-1280("添加对CreateCriteria查询的支持,修复参数顺序错误")这是可能的,但我没有使用正确的"OR"语言(例如,Restrictions.Disjunction()总是创建WHERE).
这可能吗?
我遇到了这个问题,但是我不认为我的解决方法很好,因为它不起作用,例如当您需要 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();
}
}
Run Code Online (Sandbox Code Playgroud)
喜欢
.Add(new OrHaving (Restrictions.Gt(Projections.Sum("fh.BarIn"), 0) ,
Restrictions.Gt(Projections.Sum("fh.BazIn"), 0)))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1306 次 |
| 最近记录: |