4

I have an application which uses ADO.NET datasets and data adapters in combination with remoting (client/server architecture, transmitting datasets via remoting).

I now face the following issue:

TL;DR: double value 44.850000925362000 turns into 44.850000925362004 after sending a dataset via remoting to the server.

I create a new row in the database by saving the dataset, which contains a float column (mapped to double in the dataset). The double value saved is 44.850000925362

I then read this row from the database (DataAdapter.Fill) and get the same value (checked with BitConverter.DoubleToInt64). This dataset passes via remoting to the client and is then merged into a usecase dataset on the client. Still retaining the same value.

This dataset is then merged into a usecase-dataset, the row from that is imported into a different table (because read from a view, saved to table) and a value is changed before transmitting the usecase-dataset (now containing a row in the other table).

On the client-side the value is still the same - but as soon as the dataset reaches the server, the value in question is different (although no changes were made to that specific column - it is still Unchanged and even the original value is different).

Example: Save 44.850000925362000 Read 44.850000925362000 Merge, Import, modify row - still 44.850000925362000 Send to server for saving, is 44.850000925362004 on server!

...which then causes a ConcurrencyException because the record is saved with 44.850000925362000 - but the data adapter update uses 44.850000925362004 in the WHERE condition (optimistic concurrency).

Nobody else touched that row in between.

Update

I tried setting up a test server and everything works fine there. Funny thing is: the same assembly works fine if I use it in a different service. I can't find anything in the config or startup which would explain this. I'm using a binary formatter on both, both are .NET 4.0, both use the same sourcecode... but one behaves different than the other.

Further update

I even captured the SQL statement that was being executed for the update. If I run the parameters as a WHERE clause in a SELECT statement, it fetches the correct record. So when I do this manually (via SQL Management Studio), it accepts a small delta between the value in the row and the value I give it for a condition. Still, it doesn't work at all when running the update via the adapter.

Anyway, I've given up. I've resorted to rounding it to 5 digits - way more precision than what I need in that usecase anyway. Might yield weird results if the number gets large but I don't expect that in that use case (we're talking about weight in kilograms).

urbanhusky
  • 1,336
  • 13
  • 35
  • Try sending a double directly outside of a DataSet. That shows whether the problem has anything to do with DataSet at all. Then try serializing a DataSet using BinaryFormatter. That shows whether the problem has anything to do with remoting at all. – usr Apr 29 '15 at 15:46
  • Remoting is a legacy technology that is retained for backward compatibility with existing applications and is not recommended for new development. Distributed applications should now be developed using WCF or ASP.NET Web API. See the note at the top of http://msdn.microsoft.com/en-us/library/vstudio/xws7132e.aspx for proof. – John Saunders Apr 29 '15 at 16:22
  • I never said that it was a new application ;) I'll try to reproduce it with just plain double passed as parameter to a remoting server and will also try variations of wrapping it in MarshalByValue objects (like the dataset is). – urbanhusky Apr 30 '15 at 06:05

1 Answers1

0

I can tell you what is happening here. I am not sure why, though:

If you interpret the bits of 44.850000925362000 and 44.8500009253620004 as Int64 you will get the values of 4631508893792468976 and 4631508893792468977.

As you can see, the second value is the first one incremented by one.

So, it looks like someone, somewhere interprets that double value as an Int64 and then increments it - maybe to indicate that this is a new version of the row, because you modified it.

Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443
  • The column in the dataset is ``DataType System.Double`` and ``AutoIncrement False`` - and the value in that column isn't even touched (an integer column somewhere else is incremented). So while I know that this is off by one bit, I am still nowhere closer to figuring out how or why this occurs. – urbanhusky Apr 30 '15 at 06:05