nhibernate-core icon indicating copy to clipboard operation
nhibernate-core copied to clipboard

NH-3154 - Linq group counting does not work

Open nhibernate-bot opened this issue 8 years ago • 2 comments

Alexander Zaytsev created an issue:

Following query does not work:


var result = db.Orders
    .GroupBy(x => x.ShippingDate)
    .Count() // there I want to count groups and not elements inside each group

It produces following sql:


    select
        cast(count(*) as INT) as col*0_0* 
    from
        Orders order0_ 
    group by
        order0_.ShippedDate

Which is semantically identical to following linq query:


var result = db.Orders
    .GroupBy(x => x.ShippingDate)
    .Select(x => x.Count())
    .ToList()
    .FirstOrDefault()

But it should work as count distinct


			var result = db.Orders
			               .Select(x => x.ShippingDate)
			               .Distinct()
			               .Count();


Alexander Zaytsev added a comment — :

NH-3155 is possible transformation to resolve this issue.


dthompson added a comment — :

I am running into the same issue here. Tried both NH-3155 fix branches but neither seem to resolve the issue. Thanks for all the hard work :)


ZhangJian added a comment — :

最新的版本也没有支持该功能,希望能尽快看到该功能! NHibernate团队,加油!


Oskar Berggren added a comment — :

<~jefferyzhang> I'm sorry, I cannot understand that language.


Alexander Zaytsev added a comment — :

<~oskar.berggren> he said:

"The latest version does not support this feature, and hope to see this feature as soon as possible! NHibernate team, refuel!"


Bilal Fazlani added a comment — :

Hi, Is this issue fixed?, or anyone working on it ?


Frédéric Delaporte added a comment — :

Following query, tried as a workaround, fails too:


var result = db.Orders
    .GroupBy(x => x.ShippingDate)
    .Sum(g => 1);

It issues:


select
        cast(sum(1) as INT) as col*0_0* 
    from
        Orders order0_ 
    group by
        order0_.ShippedDate

This means this bug likely affects all aggregates.


Frédéric Delaporte added a comment — :

The Distinct().Count() workaround fails with multiple grouping key. It looks like we have no workaround for this case.


var result = db.Orders
	.Select(x => new { x.ShippingDate, x.ShippedTo })
	.Distinct()
	.Count();

Fails with NotSupportedException: new <>f**AnonymousType42(ShippingDate = <100001>.ShippingDate, ShippedTo = [100001].ShippedTo) (Seems to be the type name put as the exception message. Fails at VisitExpression, at VisitNhDistinctinHqlGeneratorExpressionTreeVisitor`.)

Indeed, this would require a sub query in the from statement, which is unsupported by HQL as far as I know.

This would imply below query can not be supported:


var result = db.Orders
	.GroupBy(x => new { x.ShippingDate, x.ShippedTo })
	.Count();

I wonder then if NHibernate should really try to translate the "unique grouping key then count" case to a "distinct then count", as the more general group by case would still fails.


Thomas-Louis Simard added a comment — :

Try this as a workaround :


var result = db.Orders
    .GroupBy(group => group.ShippingDate)
    .Select(group => group.Count() / group.Count())
    .Sum();

nhibernate-bot avatar Oct 12 '17 22:10 nhibernate-bot

As a workaround group by can be replaced with subquery:

var result = db.Orders.Count(o => o == db.Orders.First(os => os.ShippingDate == o.ShippingDate));

The Distinct().Count() workaround fails with multiple grouping key. It looks like we have no workaround for this case.

With subquery it works also with multiple grouping keys:

var result2 = db.Orders.Count(o => o == db.Orders.First(os => os.ShippingDate == o.ShippingDate && os.ShippedTo == o.ShippedTo));

bahusoid avatar Aug 26 '20 05:08 bahusoid

Same issue here.

Found a workaround that is performant also!

var result = db.Orders.GroupBy(group => group.ShippingDate).Select(x => x.Key).Distinct().Count();

manuelchantada avatar Jul 12 '22 08:07 manuelchantada