Question

Is there a way to achieve SQL like this with NHibernate ICriteria or QueryOver?

select *
  from [BlogPost] b
  inner join (select blogpost_id, count(*) matchCount
                from [Tag]
                where name in ('tag X', 'tag Y')
                group by blogpost_id
             ) tagmatch 
  on tagmatch.blogpost_id = b.Id
  order by tagmatch.matchCount desc

The aim is to rank blog posts by the number of matching tags so that a post with both tag X and tag Y comes above posts with just tag X.

I've got this so far:

 DetachedCriteria
                .For<Tag>("tag")
                .Add(Restrictions.In(Projections.Property<Tag>(x => x.Name), tags.ToArray()))
                .SetProjection(Projections.Group<Tag>(t => t.BlogPost))
                    .CreateCriteria("BlogPost")
                    .SetFetchMode("BlogPost", FetchMode.Eager)
                .AddOrder(Order.Desc(Projections.RowCount()));

However, the resulting query doesn't join fetch BlogPost. Instead it returns just the ids, which leads to select n+1 when the BlogPosts are iterated.

public class BlogPost
{
  ...
  ISet<Tag> Tags {get; set;}
}

public class Tag
{
  BlogPost BlogPost { get; set; }
  string Name { get; set; }
}

This looks like a similar issue.

Is this now possible with NHibernate 3?

If not, is there an alternative solution?

I can change schema & domain model if necessary. I don't want to use SQL or HQL if possible.

Was it helpful?

Solution

I know this question was put some time ago, but I want to do about the same thing, please take a look to my question here, and this guy here, maybe you can use the idea.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top