我根本无法解决这个问题,我试图根据下面的条件求和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。
答案 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
。在您的第一个版本中,您将使用指定的TOTALS
对PAN
的所有实例进行求和。所以,这就是为什么我必须要小心谨慎,只是说它看起来像是在数据库中溢出但我们无法确定。
答案 1 :(得分:0)
如果您确定该值适合小数,则应检查Oracle数据库上的日志。对它执行Sum()操作,因此可能是原因导致数据库而不是.NET框架导致溢出。
答案 2 :(得分:0)
我猜您在数据库中有多个e.PAN == "2600000246696"
和/或多个e.PAN == "2600000246701"
第一个查询从数据库中获取所有行并为您提供总和。在Oracle中没问题(不会溢出)。将是一个很大的数字(不适合十进制)。
最后两个查询第一行占一行,第二行占一行。