我有一个应用程序,它使用 ADO.NET 数据集和数据适配器以及远程处理(客户端/服务器体系结构,通过远程处理传输数据集)。
我现在面临以下问题:
TL;DR:双倍值44.850000925362000
通过远程处理将数据集发送到服务器后变为44.850000925362004
。
我通过保存数据集在数据库中创建一个新行,该数据集包含一个浮点列(映射到数据集中的双精度)。保存的双精度值为44.850000925362
然后我从数据库(DataAdapter.Fill
)中读取此行并得到相同的值(用BitConverter.DoubleToInt64
检查)。此数据集通过远程处理传递到客户端,然后合并到客户端上的用例数据集中。仍保留相同的值。
然后将此数据集合并到用例数据集中,该行将导入到不同的表中(因为从视图中读取,保存到表中),并且在传输用例数据集(现在包含另一个表中的一行)之前更改值。
在客户端,该值仍然相同 - 但是一旦数据集到达服务器,所讨论的值就会不同(尽管没有对该特定列进行任何更改 - 它仍然是Unchanged
的,甚至原始值也不同)。
例: 保存44.850000925362000
阅读44.850000925362000
合并、导入、修改行 - 仍然44.850000925362000
发送到服务器保存,在服务器上44.850000925362004
!
。然后导致ConcurrencyException
,因为记录与44.850000925362000
一起保存 - 但数据适配器更新在WHERE
条件(乐观并发)中使用44.850000925362004
。
中间没有其他人碰过那一排。
更新
我尝试设置一个测试服务器,那里一切正常。有趣的是:如果我在不同的服务中使用它,相同的程序集可以正常工作。我在配置或启动中找不到任何可以解释这一点的内容。 我在两者上使用二进制格式化程序,两者都是 .NET 4.0,都使用相同的源代码......但一个行为与另一个不同。
进一步更新
我甚至捕获了为更新执行的 SQL 语句。如果我在SELECT
语句中将参数作为WHERE
子句运行,它会获取正确的记录。因此,当我手动执行此操作(通过 SQL 管理工作室)时,它会接受行中的值与我为条件提供的值之间的小增量。 尽管如此,通过适配器运行更新时,它根本不起作用。
无论如何,我已经放弃了。我已经诉诸于将其四舍五入为 5 位数字 - 无论如何,比我在该用例中需要的精度要高得多。如果数字变大,可能会产生奇怪的结果,但我不希望在那个用例中出现这种情况(我们谈论的是公斤的重量)。
我可以告诉你这里发生了什么。不过,我不确定为什么:
如果将44.850000925362000
位和44.8500009253620004
位解释为 Int64,您将获得4631508893792468976
和4631508893792468977
的值。
如您所见,第二个值是第一个递增 1 的值。
因此,看起来有人在某处将该双精度值解释为 Int64,然后递增它 - 也许是为了表明这是该行的新版本,因为您修改了它。