Search code examples
nhibernategroup-bycriteriaprojection

How can I recreate a SQL statement using NHibernate that has an inner select case?


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.


Solution

  • 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();