Помощь по HQL: агрегат (кол) - PullRequest
1 голос
/ 22 марта 2011

Учитывая модель 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, чтобы решить эту простую задачу?

Спасибо за любые советы!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 ]

2 голосов
/ 23 марта 2011

То, чего вы хотите достичь, - это что-то вроде этого в 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 голос
/ 22 марта 2011

Ваш первый запрос 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

Edit:

Ах, я думаю, что это может быть ошибка:

<bag name="Reports" inverse="true" fetch="join">
    <key column="ActivityId" /> <-- instead of ReportId
    <one-to-many class="Core.Models.Report"/>
</bag>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...