У меня есть приложение, которое использует наборы данных 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
, но обновление адаптера данных использует 44.850000925362004
в условии WHERE
(оптимистичный параллелизм).
Никто больше не трогал этот ряд между ними.
Обновить
Пробовал настроить тестовый сервер, там все работает. Забавно: та же сборка прекрасно работает, если я использую ее в другом сервисе. Я не могу найти ничего в конфигурации или запуске, что могло бы объяснить это. Я использую двоичный форматировщик на обоих, оба .NET 4.0, оба используют один и тот же исходный код... но один ведет себя иначе, чем другой.
Дальнейшее обновление
Я даже перехватил оператор SQL, который выполнялся для обновления. Если я запускаю параметры как предложение WHERE
в операторе SELECT
, он получает правильную запись. Поэтому, когда я делаю это вручную (через SQL Management Studio), он принимает небольшую дельту между значением в строке и значением, которое я даю для условия. Тем не менее, он вообще не работает при запуске обновления через адаптер.
В любом случае, я сдался. Я прибегал к округлению до 5 цифр - в любом случае это гораздо большая точность, чем мне нужно в этом случае использования. Может привести к странным результатам, если число станет большим, но я не ожидаю этого в этом случае использования (мы говорим о весе в килограммах).