How to get a distinct result with nHibernate and QueryOver API?

Anders picture Anders · Jan 6, 2011 · Viewed 40.7k times · Source

I have this Repository method

    public IList<Message> ListMessagesBy(string text, IList<Tag> tags, int pageIndex, out int count, out int pageSize)
    {
        pageSize = 10;
        var likeString = string.Format("%{0}%", text);
        var query = session.QueryOver<Message>()
            .Where(Restrictions.On<Message>(m => m.Text).IsLike(likeString) || 
            Restrictions.On<Message>(m => m.Fullname).IsLike(likeString));

        if (tags.Count > 0)
        {
            var tagIds = tags.Select(t => t.Id).ToList();
            query
                .JoinQueryOver<Tag>(m => m.Tags)
                .WhereRestrictionOn(t => t.Id).IsInG(tagIds);
        }            

        count = 0;
        if(pageIndex < 0)
        {
            count = query.ToRowCountQuery().FutureValue<int>().Value;
            pageIndex = 0;
        }
        return query.OrderBy(m => m.Created).Desc.Skip(pageIndex * pageSize).Take(pageSize).List();
    }

You supply a free text search string and a list of Tags. The problem is that if a message has more then one tag it is listed duplicated times. I want a distinct result based on the Message entity. I've looked at

Projections.Distinct

But it requires a list of Properties to to the distinct question on. This Message is my entity root there most be a way of getting this behaviour without supplying all of the entity properties?

Thanks in advance, Anders

Answer

Sly picture Sly · Jan 6, 2011

If you're using the ICriteria API, you need:

.SetResultTransformer(new DistinctEntityRootTransformer())

If you're using the QueryOver API, you need:

.TransformUsing(Transformers.DistinctRootEntity)

But beware, this all occurs on client side, so all the duplicate rows are still pulled.