m.edmondson
m.edmondson

Reputation: 30892

Decimal Arithmetic Overflow

I simply can't work this out, I'm attempting to sum the value of TOTAL based on the condition below, which causes an ArithmeticOverflow:

var rawData = (from e in Context.TOTALS
                where (e.PAN == "2600000246701" || e.PAN == "2600000246696")
                select e.TOTAL).Sum();

However if I seperate the condition out into two seperate queries it works:

var rawData1 = (from e in Context.TOTALS
                where (e.PAN == "2600000246696")
                select e.TOTAL).FirstOrDefault();

var rawData2 = (from e in Context.TOTALS
                 where (e.PAN == "2600000246701")
                 select e.TOTAL).FirstOrDefault();

decimal? output = rawData1 + rawData2; //output is 696768.0186M

The value clearly fits into a decimal, and I can't see why there would be any narrowing conversions going on.

I'm using Entity Framework with an Oracle backend.

Upvotes: 3

Views: 1397

Answers (3)

jason
jason

Reputation: 241641

In the first case, the sum is executed on the database. In the latter case, the sum is executed in memory, client-side, in .NET. I would suspect you are overflowing on the database. Since you didn't tell us the data type on the database and whether or not PAN is a unique identifier for TOTALS, we don't have enough information to conclude this for sure but that's definitely where I'd focus my attention first.

Edit: Here's a way to see the difference. Rewrite your code as

var rawData = (from e in Context.TOTALS
               where (e.PAN == "2600000246701" || e.PAN == "2600000246696")
               select e.TOTAL
              ).AsEnumerable()
               .Sum();

The AsEnumerable in there forces the Sum to be computed in memory. Without it, the Sum is executed on the database. In the latter case you know you are getting the overflow exception. In the former case, I suspect that you will not. If so, this says the problem is one the database.

Additionally, note that the second version of your code is not necessarily equivalent to the first version of your code. You haven't told us, although it sure looks like it, whether or not PAN is a unique identifier. If it is not, in the second case you are only pulling down one instance of TOTALS that has PAN equal to each of the given PANs. In your first version, you are summing over all instances of TOTALS with the specified PANs. So, this is why I have to be a little careful and only say it looks like you're overflowing on the database but we can't tell for sure.

Upvotes: 5

Florin Ghita
Florin Ghita

Reputation: 17643

I guess you have in database more than one e.PAN == "2600000246696" and/or more than one e.PAN == "2600000246701"

The first queryes takes all rows from database and gives you the sum. In Oracle is ok(won't overflow). Would be a big number (that not fits into decimal).

The last two queryes takes one row for first and one row for second.

Upvotes: 0

h1ghfive
h1ghfive

Reputation: 47

if you are sure that the value fits into a decimal, you should check log on your Oracle Database. The Sum() operation is executed on it, so maybe this is the cause and the overflow is caused on your database and not by the .NET framework.

Upvotes: 0

Related Questions