十进制算术溢出

时间:2012-01-26 14:03:50

标签: c# .net linq oracle entity-framework

我根本无法解决这个问题,我试图根据下面的条件求和TOTAL的值,这会导致ArithmeticOverflow:

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

但是,如果我将条件分成两个单独的查询,它可以工作:

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

该值明显符合小数,我不明白为什么会有任何缩小的转换。

我正在使用带有Oracle后端的Entity Framework。

3 个答案:

答案 0 :(得分:5)

在第一种情况下,总和在数据库上执行。在后一种情况下,总和在.NET的内存(客户端)中执行。我怀疑你在数据库上溢出来了。由于您没有告诉我们数据库中的数据类型以及PAN是否是TOTALS的唯一标识符,我们没有足够的信息来确定这一点,但这肯定是我的位置我首先关注我的注意力。

编辑:这是一种看待差异的方法。将代码重写为

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

AsEnumerable强制Sum在内存中计算。没有它,Sum将在数据库上执行。在后一种情况下,您知道您正在获得溢出异常。在前一种情况下,我怀疑你不会。如果是这样,这说明问题就是数据库。

此外,请注意,代码的第二个版本必然等同于代码的第一个版本。你没有告诉我们,虽然看起来确实如此,但PAN是否是一个唯一的标识符。如果不是,则在第二种情况下,您只会下拉一个TOTALS的{​​{1}}实例,其PAN等于每个给定的PAN。在您的第一个版本中,您将使用指定的TOTALSPAN的所有实例进行求和。所以,这就是为什么我必须要小心谨慎,只是说它看起来像是在数据库中溢出但我们无法确定。

答案 1 :(得分:0)

如果您确定该值适合小数,则应检查Oracle数据库上的日志。对它执行Sum()操作,因此可能是原因导致数据库而不是.NET框架导致溢出。

答案 2 :(得分:0)

我猜您在数据库中有多个e.PAN == "2600000246696"和/或多个e.PAN == "2600000246701"

第一个查询从数据库中获取所有行并为您提供总和。在Oracle中没问题(不会溢出)。将是一个很大的数字(不适合十进制)。

最后两个查询第一行占一行,第二行占一行。