Сгруппировать и считать с помощью nHibernate - PullRequest
4 голосов
/ 01 сентября 2010

Представьте себе следующие таблицы:

Tag (TagId, Label)

Post (PostId, Title, Content)

Пользователь (ИД пользователя, Имя)

UserPostTag (Id, UserId, PostId, TagId)

Для сообщения несколько пользователей могут добавить один или несколько тегов.

Я хочу получить с помощью nHibernate список тегов для сообщения с количеством каждого тега.

Пример или результат:

Tag(id1, label1), 7

Tag(id2, label2), 5

Tag(id3, label3), 2

Я знаю, как получить список тегов для сообщения:

IList<Tag> tagList = session.CreateCriteria<Tag>()
 .Add(Subqueries.PropertyIn("TagId",
     DetachedCriteria.For<UserPostTag>()
         .Add(Restrictions.Eq("Post.PostId", 17))
         .SetProjection(Projections.Property("Tag.TagId"))
     ))
     .List<Tag>(); 

Не могли бы вы мне помочь?

Большое спасибо!

Извините за мой английский ...

С уважением,

Antoine

Ответы [ 2 ]

0 голосов
/ 28 марта 2012

Если бы я был вами, я бы сделал дополнительного члена для класса Post, назовите его Tags и сопоставьте его как многие со многими в вашей таблице UserPostTag. В этом случае вы можете использовать следующий код для выполнения вашей задачи:

Создайте класс для получения ваших результатов:

class TagWithCount
{
  public string Label {get;set;}
  public int Count {get;set;}
}

Создать запрос (используя QueryOver):

Tag ta = null;
TagWithCount res = null;

var query = QueryOver.Of<Post>()
  .JoinAlias(x=>x.Tags, ()=>ta)
  .SelectList(x=>x.SelectGroup(() => ta.Label).WithAlias(() => res.Label),
                  .SelectCount(p=>p.Id).WithAlias(() => res.Count))
  .Where(x=>x.Id == postId)
  .TransformUsing(Transformers.AliasToBean<TagWithCount>());

Выберите фактический результат:

var res = query.GetExecutableQueryOver(session).List<TagWithCount> ();

П.С .: Я не проверял, является ли код полностью правильным, это просто чтобы дать представление.

0 голосов
/ 27 апреля 2011

Если я прав, создайте запрос HQL следующим образом:

@"SELECT new Tag(tag.Id, tag.Label), count(cloud.User)
FROM UserPostTag cloud 
    JOIN cloud.Tag tag
WHERE cloud.Post.Id = :postId
GROUP BY tag.Id, tag.Label"

Введите это в вызове CreateQuery, он будет работать только в том случае, если у вас есть конструктор Tag, который принимает идентификатор и метку.(Не забудьте установить параметр postId.)

Это возвращает список с тегом и списком в массиве, я считаю.

Обновление: если это не работает, вы можете создатьновый класс TagCount, который имеет тег и счетчик и изменяет синтаксис выбора на что-то вроде следующего:

SELECT new TagCount(tag.Id, tag.Label, count(cloud.User))

(Отказ от ответственности: я не пробовал это.)

...