In my project I have been using Linq's Sum()
a lot. It's powered by NHibernate on MySQL. In my Session Factory
I have explicitly asked NHibernate to deal with exactly 8 decimal places when it comes to decimals
:
public class DecimalsConvention : IPropertyConvention
{
public void Apply(IPropertyInstance instance)
{
if (instance.Type.GetUnderlyingSystemType() == typeof(decimal))
{
instance.Scale(8);
instance.Precision(20);
}
}
}
However, I found out that .Sum()
rounds up the numbers in 5 decimal places:
var opasSum = opasForThisIp.Sum(x => x.Amount); // Amount is a decimal
In the above statement opaSum
equals to 2.46914 while it should be 2.46913578 (calculated directly on MySQL). opasForThisIp
is of type IQueryable<OutgoingPaymentAssembly>
.
I need all the Linq calculations to handle 8 decimal places when it comes to decimals
.
Any ideas of how to fix this?
Edit 1: I have found var opasSum = Enumerable.Sum(opasForThisIp, opa => opa.Amount);
to produce the correct result, however the question remains, why .Sum()
rounds up the result and how can we fix it?
Edit 2: The produced SQL seems to be problematic:
select cast(sum(outgoingpa0_.Amount) as DECIMAL(19,5)) as col_0_0_
from `OutgoingPaymentAssembly` outgoingpa0_
where outgoingpa0_.IncomingPayment_id=?p0
and (outgoingpa0_.OutgoingPaymentTransaction_id is not null);
?p0 = 24 [Type: UInt64 (0)]
Edit 3: var opasSum = opasForThisIp.ToList().Sum(x => x.Amount);
also produces the correct result.
Edit 4: Converting the IQueryable<OutgoingPaymentAssembly>
to an IList<OutgoingPaymentAssembly>
made the original query: var opasSum = opasForThisIp.Sum(x => x.Amount);
to work.