Объединяйте таблицы с вложенным счетчиком выбора и группируйте в Nhibernate HQL - PullRequest
2 голосов
/ 04 марта 2010

У меня есть таблица сообщений, голосований и комментариев.Каждый пост может иметь N голосов и N комментариев.Я пытался найти способ выполнить этот запрос, используя Nhibernate HQL, но безуспешно.

 SELECT P.Id, P.Title, P.TextDescription, ISNULL(V.TotalVotes,0), ISNULL(C.TotalComments, 0)
 FROM
 Post P

 LEFT JOIN
   (SELECT 
    PostId, count(PostId) as TotalVotes 
    FROM Vote 
    GROUP BY PostId) V
 ON V.PostId = P.Id 

 LEFT JOIN 
    (SELECT 
     PostId, count(PostId) as TotalComments
     FROM Comment 
     GROUP BY PostId) C
 ON C.PostId = P.id 

Я вставил агрегаты GROUP BY во вложенные операторы SELECT, потому что я хочу сгруппировать только PostId, а не все остальные столбцы,Классы моего домена:

Запись - свойства:

int Id  { get; set; }
string Title { get; set; }
string TextDescription { get; set; }
IList<Comment> Comments { get; set; } -> HasMany
IList<Vote> Votes { get; set; } -> HasMany

Комментарий - свойства:

int Id  { get; set; }
Post Post { get; set; } -> reference

Голосование

int Id  { get; set; }
Post Post { get; set; } -> reference

Я действительноозадачен по этому поводу.Я надеюсь, что я не пойду в неправильном направлении.Может быть, я должен просто использовать атрибут формулы Nhibernate, в котором я могу объявить произвольное выражение SQL для моего счета.

Любая помощь будет очень признательна ..

Спасибо!

Ответы [ 2 ]

2 голосов
/ 08 марта 2010

Для того, что вы пытаетесь сделать, вам нужно написать любой запрос HQL Так как у вас есть коллекции в ваших классах, и вы отобразили их в своих файлах .hbm.xml, например (если вы используете свободный nhibernate, игнорируйте это)

<bag name="Comments" inverse="true" lazy="extra">
    <key column="CommentId" />
    <one-to-many class="Comment,mylib" />
</bag>

<bag name="Votes" inverse="true" lazy="extra">
    <key column="VoteId" />
    <one-to-many class="Vote,mylib" />
</bag>

при звонке

Post post = ISession.Get<Post>(postId);

коллекции Comments и Votes инициализируются прокси. Когда вы касаетесь коллекции как таковой

post.Comments.Count

NHibernate запустит выборочное количество (*) для комментариев с идентификатором сообщения postId.

Если вы абсолютно хотите реализовать это с помощью формулы (потому что вы хотите, чтобы счетчик просматривался каждый раз, когда вы получаете сообщение) снова, вам не понадобится запрос HQL (или критерии в этом отношении)

EDIT: Поскольку вам не нужны формулы и вы хотите получить результат за один цикл, вот решение на HQL (требуется приведенное выше отображение коллекции)

IQuery query = nhSession.CreateQuery("select p, count(p.Comments), p.(p.Votes) from Post p where p.id = :postId");
query.SetInt32("postId", postId);
object result = query.UniqueResult();

где result - массив (я думаю, ArrayList), где result [0] - объект типа Post, result [1] - количество комментариев (int / long), а result [2] - количество голосов (int / long )

0 голосов
/ 04 марта 2010

Если вы сопоставите свои коллекции с помощью lazy = "extra", их свойство Count не вызовет загрузку коллекции.

...