Reporting query containing sum crashes when there are no rows

Description

Sample code:
q1 = from t in session.Query<Account>() select t;
sum = q1.Sum<Account>(p => p.Balance);
crashes when there are no rows in the table.
Old equivalent code:
query = session.CreateQuery("select Sum(a.Balance) from Account a");
sum = query.UniqueResult<decimal>();

behaves correctly - it returns 0.

Stack trace:

NHibernate.Exceptions.GenericADOException was unhandled
Message="Could not execute query[SQL: SQL not available]"
Source="NHibernate"
SqlString="SQL not available"
StackTrace:
w NHibernate.Impl.SessionImpl.List(IQueryExpression queryExpression, QueryParameters queryParameters, IList results)
w NHibernate.Impl.SessionImpl.List(IQueryExpression queryExpression, QueryParameters parameters)
w NHibernate.Impl.ExpressionQueryImpl.List()
w NHibernate.Linq.NhQueryProvider.Execute(Expression expression)
w NHibernate.Linq.NhQueryProvider.Execute[TResult](Expression expression)
w System.Linq.Queryable.Sum[TSource](IQueryable`1 source, Expression`1 selector)
w NHLinqSum.Program.Main(String[] args) w D:\projekty\NHLinqSum\NHLinqSum\Program.cs:wiersz 56
w System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
w System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
w Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
w System.Threading.ThreadHelper.ThreadStart_Context(Object state)
w System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
w System.Threading.ThreadHelper.ThreadStart()
InnerException: System.ArgumentException
Message="Wartość „" nie jest typu „System.Decimal" i nie może być użyta w tej kolekcji rodzajowej.\r\nNazwa parametru: value"
Source="mscorlib"
ParamName="value"
StackTrace:
w System.ThrowHelper.ThrowWrongValueTypeArgumentException(Object value, Type targetType)
w System.Collections.Generic.List`1.VerifyValueType(Object value)
w System.Collections.Generic.List`1.System.Collections.IList.Add(Object item)
w NHibernate.Util.ArrayHelper.AddAll(IList to, IList from)
w NHibernate.Engine.Query.HQLQueryPlan.PerformList(QueryParameters queryParameters, ISessionImplementor session, IList results)
w NHibernate.Impl.SessionImpl.List(IQueryExpression queryExpression, QueryParameters queryParameters, IList results)
InnerException:

Environment

None

Attachments

1

Activity

Show:

Farzad Panahi January 7, 2011 at 5:08 PM

I am using NH3 and have the same problem but the following work around does not work for me:

query.Sum(x => (decimal?)x.Amount) ?? 0;

I traced the code. The problem shows up here:
NHibernate.Util.ArrayHelper.AddAll(IList to, IList from) in d:\CSharp\NH\nhibernate\src\NHibernate\Util\ArrayHelper.cs:201

// NH-specific
public static void AddAll(IList to, IList from)
{
foreach (object obj in from)
{
to.Add(obj); //<---- line 201
}
}

At run-time:

  • "to" is a List<decimal?>

  • "from" is a List<object>

  • "obj" is null

It seems that there is a bug in .Net 3.5 which is causing this problem. Basically you cannot add null to an IList even though that IList is referring to a List of nulleable type like decimal?.

http://stackoverflow.com/questions/3808256/cant-add-null-to-list-of-nullables

You can generate the same error under .net 3.5 by:

IList d = new List<decimal?>();
decimal? o = null;
d.Add(o);

So do you guys have a fix for this? Can we have a AddAll .net 3.5 compatible method in ArrayHelper class?

--------------------- Original stack trace:

[ArgumentException: The value "" is not of type "System.Nullable`1[System.Decimal]" and cannot be used in this generic collection.
Parameter name: value]
System.ThrowHelper.ThrowWrongValueTypeArgumentException(Object value, Type targetType) +122
System.Collections.Generic.List`1.VerifyValueType(Object value) +36
System.Collections.Generic.List`1.System.Collections.IList.Add(Object item) +19
NHibernate.Util.ArrayHelper.AddAll(IList to, IList from) in d:\CSharp\NH\nhibernate\src\NHibernate\Util\ArrayHelper.cs:201
NHibernate.Engine.Query.HQLQueryPlan.PerformList(QueryParameters queryParameters, ISessionImplementor session, IList results) in d:\CSharp\NH\nhibernate\src\NHibernate\Engine\Query\HQLQueryPlan.cs:139
NHibernate.Impl.SessionImpl.List(IQueryExpression queryExpression, QueryParameters queryParameters, IList results) in d:\CSharp\NH\nhibernate\src\NHibernate\Impl\SessionImpl.cs:652

[GenericADOException: Could not execute query[SQL: SQL not available]]
NHibernate.Impl.SessionImpl.List(IQueryExpression queryExpression, QueryParameters queryParameters, IList results) in d:\CSharp\NH\nhibernate\src\NHibernate\Impl\SessionImpl.cs:662
NHibernate.Impl.SessionImpl.List(IQueryExpression queryExpression, QueryParameters parameters) in d:\CSharp\NH\nhibernate\src\NHibernate\Impl\SessionImpl.cs:634
NHibernate.Impl.ExpressionQueryImpl.List() in d:\CSharp\NH\nhibernate\src\NHibernate\Impl\ExpressionQueryImpl.cs:63
NHibernate.Linq.NhQueryProvider.ExecuteQuery(NhLinqExpression nhLinqExpression, IQuery query, NhLinqExpression nhQuery) in d:\CSharp\NH\nhibernate\src\NHibernate\Linq\NhQueryProvider.cs:78
NHibernate.Linq.NhQueryProvider.Execute(Expression expression) in d:\CSharp\NH\nhibernate\src\NHibernate\Linq\NhQueryProvider.cs:27
NHibernate.Linq.NhQueryProvider.Execute(Expression expression) in d:\CSharp\NH\nhibernate\src\NHibernate\Linq\NhQueryProvider.cs:102
System.Linq.Queryable.Sum(IQueryable`1 source, Expression`1 selector) +274

Patrick Earl December 24, 2010 at 4:51 PM

I did fix a bug that was breaking empty sums of nullables in r5337.

Patrick Earl December 24, 2010 at 4:48 PM

Throwing an exception is consistent with Linq to SQL and EF. Instead of always adding the extra coalesce to the query automatically, you can add it yourself if you need it. For example:

Kamil Serwus August 16, 2010 at 2:03 AM

I have the same problem.

I resolved it by changing query:
decimal? sum = query.Sum(p => (decimal?)p.Price);

Won't Fix

Details

Assignee

Reporter

Components

Fix versions

Affects versions

Priority

Who's Looking?

Open Who's Looking?

Created March 6, 2010 at 2:39 AM
Updated July 25, 2012 at 5:54 AM
Resolved December 24, 2010 at 4:51 PM
Who's Looking?