2011-03-22 90 views
1

給定模型Activity,其中包含具有報告類型(一對多)模型的包。我想獲得所有活動的列表,其中包含每項活動的報告數量。這兩個查詢不會導致任何好處,計數器始終爲1(這是錯誤的):HQL幫助:總計(計數)

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合適的查詢來解決這個簡單的任務?

Thx for any tipps! 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; } 

} 

回答

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> 
+0

至於第一個查詢:不幸的是,我仍然得到每個活動一(並且只有一個)報告作爲計數。至於第二個查詢,這正是我上面寫的 - 我的也是正確的,但沒有很好格式化;-) – sl3dg3 2011-03-22 16:39:33

+0

@ sl3dg3對不起,我沒有正確測試這些。我只是在測試環境中測試了這些查詢,並且它們運行良好。你可以發佈映射和類定義嗎? – 2011-03-22 22:42:38

+0

@Florian我在原帖中添加了映射... – sl3dg3 2011-03-23 08:35:26

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())工作。

的正式工作組由語法很麻煩,因爲你需要組由所有映射的活動性質:

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 
+0

測試這一點,但生成的SQL('選擇activity0_.ActivityId如col_0_0_, \t計數(reports1_.ReportId)作爲col_1_0_,activity0_.ActivityId如ActivityId12_,activity0_.Title如Title12_ 從活動activity0_,報告reports1_ 其中activity0_。 ActivityId = reports1_.ReportId')失敗說:'Column'Activity.ActivityId'在選擇列表中無效,因爲它不包含在聚合函數或GROUP BY子句中。「 – sl3dg3 2011-03-23 09:30:19

+0

我更新了我的答案。 – 2011-03-23 10:11:53

+0

Thx - 事實證明我有一個映射 - 錯誤(見上文)。到目前爲止,你已經提出了相同的解決方案:-) – sl3dg3 2011-03-23 10:39:38