Двойное значение изменилось после его передачи через удаленное взаимодействие .NET.

У меня есть приложение, которое использует наборы данных 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 цифр - в любом случае это гораздо большая точность, чем мне нужно в этом случае использования. Может привести к странным результатам, если число станет большим, но я не ожидаю этого в этом случае использования (мы говорим о весе в килограммах).


person urbanhusky    schedule 29.04.2015    source источник
comment
Попробуйте отправить двойное значение непосредственно за пределы DataSet. Это показывает, имеет ли проблема какое-либо отношение к DataSet. Затем попробуйте сериализовать DataSet с помощью BinaryFormatter. Это показывает, имеет ли проблема какое-либо отношение к удаленному взаимодействию.   -  person usr    schedule 29.04.2015
comment
Удаленное взаимодействие — это устаревшая технология, которая сохраняется для обратной совместимости с существующими приложениями и не рекомендуется для новых разработок. Распределенные приложения теперь должны разрабатываться с использованием веб-API WCF или ASP.NET. См. примечание в верхней части msdn.microsoft.com/en-us. /library/vstudio/xws7132e.aspx для доказательства.   -  person John Saunders    schedule 29.04.2015
comment
Я никогда не говорил, что это новое приложение ;) Я попытаюсь воспроизвести его, просто передав его в качестве параметра удаленному серверу, а также попытаюсь обернуть его в объекты MarshalByValue (как набор данных).   -  person urbanhusky    schedule 30.04.2015


Ответы (1)


Я могу рассказать вам, что здесь происходит. Я не уверен, почему, хотя:

Если вы интерпретируете биты 44.850000925362000 и 44.8500009253620004 как Int64, вы получите значения 4631508893792468976 и 4631508893792468977.

Как видите, второе значение — это первое, увеличенное на единицу.

Итак, похоже, что кто-то где-то интерпретирует это двойное значение как Int64, а затем увеличивает его - может быть, чтобы указать, что это новая версия строки, потому что вы ее изменили.

person Daniel Hilgarth    schedule 29.04.2015
comment
Столбец в наборе данных — это DataType System.Double и AutoIncrement False, и значение в этом столбце даже не затрагивается (инкрементируется целочисленный столбец в другом месте). Поэтому, хотя я знаю, что это немного не так, я все еще не приблизился к выяснению того, как и почему это происходит. - person urbanhusky; 30.04.2015