DataSet Loses Row. It's true an terrible.

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

I have a dataset with 2 tables (father and child table) and a
relation between them with cascade for update and delete.
I also have a client application and a remote application.
If in the client application I delete a existing father's row and afterwards
create the same father's row with the same field values and a new child row
and call a remote application' method by remoting passing this dataset
(making the serialization), you will see that there is no child row in
dataset at the remote application's method.
I think serialization lost the child row. This is a terrible problem.
The child row is indeed there. I'm seeing the row in a datagrid and I also
put a
break point and saw it in the dataset table but after the seralization the
child row vanished.
But note that the child row has vanished only if I create the father's row
with the same field's value from the deleted father's row.
I'm using framework 1.1.
Can someone help me?
 
Do you known that there is a problem like this in DataSets? Why are you
suggesting to call "AcceptChanges" before the serialization.
I can't call "AcceptChanges" before serialization because I'm passing this
DataSet to another application (a dotnet service) which will record the
dataset's changes in a database using adapters.
I'm serializing calling a method of a serializable class (service).
The service.config is like this:
<channels>
<channel ref="tcp" port="8080">
<serverProviders>
<formatter ref="binary" TypeFilterLevel="Full" />
</serverProviders>
</channel>
Can you help me?
Thanks.
 
Yes Mauricio, I distinctly remember such a problem. Now I don't remember it
quite well, but I distinctly remember deleted rows getting missed out on the
other end. I had faced this problem in debugging the DataSetSurrogate
(search MS Knowledgebase for that keyword).

Datasets are serialized as XML, and I had traced it as a limitation of XML
and something to do with a default value on a column that had floating point
(decimal/double etc.) datatype. It was something on the lines of - while
trying to serialize complete information, it gets confused between the
default value as being 0.0 or 0.0F, it can't seem to compare the two so it
dumps the row (something on those lines). I take it you are in a remoting
scenario, so this is exactly the same as the situation I was in.

Now I can tell you that I found a way out, and maybe I can help you too
(Sorry I had been busy the last few days and just didn't get a chance to
read messages in the newsgroup).
Unfortunately this was a way back so I cannot clearly recall what I did ---

Try one of the following --
a) Make this dataset a property of another class, and send that class back
instead.
b) Throw this dataset in a dataset surrogate instance (Search Microsoft
knowledgebase for the keyword "DatasetSurrogate").
c) Do you have default values mentioned on any of the columns that are
floating types on that row? Remove the default value if you do.

Also, right before serialization, can you save your Dataset, including
diffgram, and attempt to serialize it and de-serialize it using
BinaryFormatter/ See if that ended up knocking the row out - in other words,
isolate the problem in such a way that
a) You are sure it is the serialization that is eating up the rows.
b) You can show a quick code sample here demonstrating the problem - since I
cannot sit with you and debug line by line.

Let me know :-)

- Sahil Malik
http://dotnetjunkies.com/weblog/sahilmalik
 
Now I am trying your ideas, but this is a terrible problem.
After that I detected that others apllications I did in the past have the
same problem.

Thanks.

Mauricio
ControlBase
Industrial Automation - (Brazil)
 
Hi Sahil.
Now I known that serialization causes the problem.
I made this:

Dim dsOriginal As DataSetUsuariosPermissoes =
Me.DataSetUsuariosPermissoes.GetChanges
Dim dsAux As DataSetUsuariosPermissoes
Dim mySerializer As Xml.Serialization.XmlSerializer = New
Xml.Serialization.XmlSerializer(GetType(DataSetUsuariosPermissoes))
Dim myWriter As IO.StreamWriter = New IO.StreamWriter("myFileName.xml")
mySerializer.Serialize(myWriter, ds)
myWriter.Close()
Dim myFileStream As IO.FileStream = New IO.FileStream("myFileName.xml",
IO.FileMode.Open)
dsAux = CType(mySerializer.Deserialize(myFileStream),
DataSetUsuariosPermissoes)
myFileStream.Close()

And dsOriginal <> dsAux. dsAux lost a row.
 
Hi, Sahil
Above there is the whole code.
It is need to create a Form (Form1), copy the variable declarations and
copy the statements inside the Form1_Load().
I hope this example can clear the problem and you can help me.
Thanks.
Mauricio Pires
ControlBase (Brazil)

'Variable declarations"
Friend FatherTable As New DataTable("FatherTable")
Friend ChildTable As New DataTable("ChildTable")

Friend dsOriginal As New DataSet
Friend dsRead As DataSet
Friend WithEvents DataGridOriginalFather As System.Windows.Forms.DataGrid
Friend WithEvents DataGridOriginalChild As System.Windows.Forms.DataGrid

'Form_Load
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

Me.ClientSize = New System.Drawing.Size(600, 266)

'Creating the DataGrids
Me.DataGridOriginalFather = New System.Windows.Forms.DataGrid
Me.DataGridOriginalFather.CaptionText = "Original Father"
Me.DataGridOriginalFather.Location = New System.Drawing.Point(56, 24)
Me.DataGridOriginalFather.Name = "DataGridOriginalFather"
Me.DataGridOriginalFather.Size = New System.Drawing.Size(184, 112)

Me.DataGridOriginalChild = New System.Windows.Forms.DataGrid
Me.DataGridOriginalChild.CaptionText = "Original Child"
Me.DataGridOriginalChild.Location = New System.Drawing.Point(40, 168)
Me.DataGridOriginalChild.Name = "DataGridOriginalChild"
Me.DataGridOriginalChild.Size = New System.Drawing.Size(232, 80)

Me.DataGridDeserializedFather = New System.Windows.Forms.DataGrid
Me.DataGridDeserializedFather.CaptionText = "Deserialized Father"
Me.DataGridDeserializedFather.Location = New
System.Drawing.Point(344, 24)
Me.DataGridDeserializedFather.Name = "DataGridDeserializedFather"
Me.DataGridDeserializedFather.Size = New System.Drawing.Size(184, 120)

Me.DataGridDeserializedChild = New System.Windows.Forms.DataGrid
Me.DataGridDeserializedChild.CaptionText = "Deserialized Child (the
child vanished)"
Me.DataGridDeserializedChild.HeaderForeColor =
System.Drawing.SystemColors.ControlText
Me.DataGridDeserializedChild.Location = New
System.Drawing.Point(328, 168)
Me.DataGridDeserializedChild.Name = "DataGridDeserializedChild"
Me.DataGridDeserializedChild.Size = New System.Drawing.Size(232, 80)

Me.Controls.Add(Me.DataGridOriginalChild)
Me.Controls.Add(Me.DataGridOriginalFather)
Me.Controls.Add(Me.DataGridDeserializedFather)
Me.Controls.Add(Me.DataGridDeserializedChild)

'Creating 2 tables (father and child tables) and a relation
Dim fatherCol1 As New DataColumn("FatherCol1")
Dim childCol1 As New DataColumn("ChildCol1")
Dim childCol2 As New DataColumn("ChildCol2")

FatherTable.Columns.Add(fatherCol1)
ChildTable.Columns.Add(childCol1)
ChildTable.Columns.Add(childCol2)

dsOriginal.Tables.Add(FatherTable)
dsOriginal.Tables.Add(ChildTable)
dsOriginal.Relations.Add("FatherChildRelation", fatherCol1, childCol1)

'Creating a father row
FatherTable.Rows.Add(New Object() {"Father1"})
Me.dsOriginal.AcceptChanges()

'Deleting the father row that was created above
FatherTable.Rows(0).Delete()

'Creating the same father row again
FatherTable.Rows.Add(New Object() {"Father1"})

'Creating a child row
ChildTable.Rows.Add(New Object() {"Father1", "Child1"})

'Serialization to "myFile.xml"
Dim mySerializer As New
System.Xml.Serialization.XmlSerializer(GetType(DataSet))
Dim myWriter As IO.StreamWriter = New
IO.StreamWriter("myFileName.xml")
mySerializer.Serialize(myWriter, dsOriginal)
myWriter.Close()

'Deserialization (see that dataset lost the child row)
Dim myFileStream As IO.FileStream = New
IO.FileStream("myFileName.xml", IO.FileMode.Open)
' Calls the Deserialize.
dsRead = CType( _
mySerializer.Deserialize(myFileStream), DataSet)
myFileStream.Close()

'This DataDrid show the DataSet with one father and one child rows
(OK)
Me.DataGridOriginalFather.SetDataBinding(dsOriginal, "FatherTable")
Me.DataGridOriginalChild.SetDataBinding(dsOriginal,
"FatherTable.FatherChildRelation")

'These DataGrids show the dataset with one father and anyone chid
row (The child vanished)
Me.DataGridDeserializedFather.SetDataBinding(Me.dsRead, "FatherTable")
Me.DataGridDeserializedChild.SetDataBinding(Me.dsRead,
"FatherTable.FatherChildRelation")

End Sub

'------ THE END -------------
 
Back
Top