帮助HQL:聚合(计数)

时间:2011-03-22 12:05:54

标签: nhibernate hql

给定模型Activity包含一个包含类型为Report的模型的包(一对多)。我想获得所有活动的清单,其中包含每项活动的报告数量。这两个查询没有任何好处,计数器总是1(这是错误的):

select act, (select count(r) from act.Reports r) from Activity act

或者:

select act, count( elements(act.Reports) ) from Activity act group by act.ActivityId, act.Title

是否可以在HQL中编写正确的查询来解决这个简单的任务?

任何tipps的Thx! sl3dg3

编辑: 映射之后。活性:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
    <class
        name="Core.Models.Config.Activity, Core"
        table="Activity"
    >

        <!-- primary key -->
        <id name="ActivityId" type="Int32" unsaved-value="0" access="property">
            <column name="ActivityId" not-null="true"/>
            <generator class="identity" />
        </id>

        <!-- Properties -->
        <many-to-one name="Title" fetch="join" cascade="all"/>

        <!-- One-To-Many Reports -->
        <bag name="Reports" inverse="true" fetch="join">
            <key column="ReportId" />
            <one-to-many class="Core.Models.Report"/>
        </bag>

    </class>
</hibernate-mapping>

制图报告:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
    <class
        name="Core.Models.Report, Core"
        table="Report"
    >

    <!-- primary key -->
    <id name="ReportId" type="Int32" unsaved-value="0" access="property">
        <column name="ReportId" not-null="true"/>
        <generator class="identity" />
    </id>

    <!-- Properties (shortened - there are more many-to-one and one bag -->
    <property name="Created" />
    <many-to-one name="Activity" column="ActivityId" />

</class>

课堂活动:

public class Activity
{

    public Activity()
    {
        Title = new Translation();
    }

    public virtual int ActivityId { get; set; }

    public virtual Translation Title { get; set; }

    public virtual IList<Report> Reports { get; set; }
}

班级报告:

public class Report
{

    /// <summary>
    /// HNIBERNATE ONLY
    /// </summary>
    public Report() 
    { }

    /// <summary>
    /// Init Report
    /// </summary>
    public Report(User author)
    {
        // ... Shortened
        Activity = new Activity();
    }

    public virtual Activity Activity { get; set; }

}

2 个答案:

答案 0 :(得分:2)

您希望在 SQL

中实现的目标是这样的
select 
  act.*, 
 (select count(*) from Reports rep where rep.id = act.reportId)
from Activity act

使用size()最简单,但不幸的是无效

select act, size(act.Reports)
from Activity act

根据文档,size在select子句中不可用。有趣的是,它实际上可以用.size ,但不能用size(),实际上应该是等效的:

select act, act.Reports.size
from Activity act

可能值得一个功能请求也要使函数语法(size())正常工作。

正式运行的语法组很麻烦,因为您需要按所有映射的Activity属性进行分组:

select act, count(*)
from Activity act left join act.Reports rep
group by act.id, act.Name, act.Whatever

所以我最后尝试了这个变体,似乎正是你需要的

select act, (select count(*) from act.Reports)
from Activity act

答案 1 :(得分:1)

您的第一个HQL查询语法错误。试试这个:

select act, (select count(*) from act.Reports) from Activity act

您的第二个HQL查询无法工作,因为您需要GROUP BY子句中的所有列。试试这个:

select act.ActivityId, act.Title, count( elements(act.Reports) ) 
from Activity act 
group by act.ActivityId, act.Title

修改

啊,我认为这可能是错误:

<bag name="Reports" inverse="true" fetch="join">
    <key column="ActivityId" /> <-- instead of ReportId
    <one-to-many class="Core.Models.Report"/>
</bag>