7

I'm trying to do the equivalent of this SQL Code

SELECT 
ID
SUM(CASE WHEN myProperty = 2 THEN 1 ELSE 0 END) as nbRowWithValueOf2,
SUM(CASE WHEN myProperty = 3 THEN 1 ELSE 0 END) as nbRowWithValueOf3
FROM Foo
GROUP BY ID

With Nhibernate.

So far I tried

queryable = queryable
    .Select(
        Projections.Group<Foo>(c => c.ID),
        Projections.Sum<Foo>(c => c.myProperty == MyEnum.Two ? 1 : 0)
        Projections.Sum<Foo>(c => c.myProperty == MyEnum.Three ? 1 : 0)
)

But this gives me the following error:

Could not determine member from IIF((Convert(c.myProperty) = 2), 1, 0)

Do you have any idea ?

EDIT 1 : I can get the result with 2 queries but I want to do this in only 1 query.

EDIT 2 : I'm using QueryOver here.

Andrew Whitaker
  • 124,656
  • 32
  • 289
  • 307
remi bourgarel
  • 9,231
  • 4
  • 40
  • 73

1 Answers1

15

I think this should work (QueryOver syntax):

queryover = queryover
    .Select(
        Projections.Group<Foo>(c => c.ID),
        Projections.Sum(
            Projections.Conditional(
                Restrictions.Where<Foo>(f => f.myProperty == MyEnum.Two),
                Projections.Constant(1),
                Projections.Constant(0))),
        Projections.Sum(
            Projections.Conditional(
                Restrictions.Where<Foo>(f => f.myProperty == MyEnum.Three),
                Projections.Constant(1),
                Projections.Constant(0))));

Which should give you the following SQL:

SELECT this_.ID as y0_,
       sum((case
              when this_.myProperty = 2 /* @p0 */ then 1 /* @p1 */
              else 0 /* @p2 */
            end))               as y1_,
       sum((case
              when this_.myProperty = 3 /* @p3 */ then 1 /* @p4 */
              else 0 /* @p5 */
            end))               as y2_
FROM   [Foo] this_
GROUP  BY this_.ID
Oskar Berggren
  • 5,583
  • 1
  • 19
  • 36
Andrew Whitaker
  • 124,656
  • 32
  • 289
  • 307
  • Do you know how this will look like if I use QueryOver instead? – Alexey Zimarev Jun 26 '12 at 14:45
  • I mean using SelectGroup instead of Projections.Group, SelectSum instead of Projections.Sum and so on, so QueryOver with inline syntax to be precise with terms – Alexey Zimarev Jun 27 '12 at 08:15
  • The problem is that there's no inline syntax for `Projections.Conditional`. You have to drop back into criteria for the `case when x then y end`. – Andrew Whitaker Jun 27 '12 at 12:24
  • The problem with QueryOver is that it doesn't support Any in its where clause – Beatles1692 Apr 27 '15 at 15:17
  • @Beatles1692: What do you mean exactly? Do you mean generating an `any` clause in the generated SQL? If so, this is possible with the `WithSubquery.WhereSome`. If you mean using LINQ's `.Any` extension method, no that probably won't work because LINQ syntax isn't the same as the QueryOver API – Andrew Whitaker Apr 27 '15 at 15:21
  • Yes I was talking about the latter.Where we can have Any in our Where clause but it's not possible in a QueryOver. – Beatles1692 Apr 27 '15 at 21:44