0

Давайте предположим, что у меня есть этот простой n-n таблицу (между people и product):Получить количество строк с уникальными идентификаторами

//id people_id product_id 
    1   1   1 
    2   1   3 
    3   1   5 
    4   2   1 

И этот класс (уже отображенной):

public class PeopleProduct 
{ 
    public virtual int TableId { get; set; } //Mapped to id 
    public virtual int PeopleId { get; set; } //Mapped to people_id 
    public virtual Product Product { get; set; } //Mapped to product_id 
} 

Как вы можете см., есть два people, первый с 3 products, а второй с только 1.

Как я могу получить количество уникальных people_id с помощью CreateCriteria?

В настоящее время я пытаюсь использовать это один:

var crit = StatelessSession.CreateCriteria<PeopleProduct>() 
    .SetProjection(Projections.ProjectionList() 
     .Add(Projections.Count<PeopleProduct>(c => c.PeopleId)) 
     .Add(Projections.Group<PeopleProduct>(g => g.PeopleId))); 

var count = Convert.ToInt64(crit.UniqueResult()); 

Но он всегда возвращает список с массивом [число, идентификатор]:

[3, 1] and [2, 1] 

Это не самый лучший потому что эта таблица может вернуть тысячи people_id.

ответ

1

Использование CountDistinct.

var numberOfDistinctPeople = StatelessSession.CreateCriteria<PeopleProduct>() 
    .SetProjection(Projections.CountDistinct<PeopleProduct>(c => c.PeopleId)) 
    .UniqueResult(); 

Кстати, знаете ли вы, что вы можете использовать QueryOver, что то же самое с более синтаксисом? HQL/Linq является еще более мощным и лучше использовать для статических запросов, подобных этому.

+0

Спасибо, я знал об этом, но я использовал 'CreateCriteria' для других запросов (настраиваемых по каждой таблице). Говоря о QueryOver, есть ли разница в производительности между обоими? –

0

И, наконец, это сработало!

var crit = StatelessSession.CreateCriteria<PeopleProduct>() 
    .SetProjection(Projections.ProjectionList() 
      .Add(Projections.Count(Projections.Distinct(
        Projections.Property<PeopleProduct>(p => p.PeopleId))))); 

var count = Convert.ToInt64(crit.UniqueResult()); 

EDIT: Там лучший ответ (и менее многословный) ...