views:

90

answers:

1

I am trying to recreate something like the following SQL using NHibernate criteria:

select Range, count(*) from (
   select
      case
         when ent.ID between 'A' and 'N' then 'A-M'
         else 'Other'
      end as Range
   from Subject
) tbl
group by tbl.Range

I am able to create the inner select as follows:

session.CreateCriteria<Subject>()
   .SetProjection(
      Projections.Conditional(
         Expression.Between("Name", "A", "N"),
         Projections.Constant("A-M"),
         Projections.Constant("Other")))
   .List();

However, I can't figure out how to pipe those results into a grouping by row count.

A: 

This should work...

session.CreateCriteria<Subject>()
   .SetProjection(
       Projections.ProjectionList()
          .Add(
             Projections.GroupProperty(
                Projections.Conditional(
                   Restrictions.Between("Name", "A", "N"),
                   Projections.Constant("A-M"),
                   Projections.Constant("Other"))))
        .Add(Projections.RowCount()))
   .List();

...but it doesn't. So you can do this instead:

session.CreateCriteria<Subject>()
   .SetProjection(
      Projections.ProjectionList()
         .Add(
            Projections.GroupProperty(
               Projections.SqlProjection(
                  @"case
                       when Name between 'A' and 'N' then 'A-M'
                       else 'Other' 
                    end as Range",
                  new[] { "Range" },
                  new[] { TypeFactory.GetStringType(5) })))
         .Add(Projections.RowCount()))
   .List();
Diego Mijelshon
Thanks, that does work, but I was hoping not to drop down into SQL. Any idea why your first example doesn't work?
brianberns
I'm not sure. It might be a bug in NHibernate. But feel free to experiment with it, maybe I missed something.
Diego Mijelshon