Microsoft Knowledge Base Article
This article contents is Microsoft Copyrighted material.
©2005-©2007 Microsoft Corporation. All rights reserved.
Terms
of Use |
Trademarks
Article ID: 325697 - Last Review: October 31, 2003 - Revision: 3.0
FIX: Null Values Are Returned for Fabricated DataColumns When a DataSet Is Deserialized from a DiffGram
This article was previously published under Q325697
On This Page
SYMPTOMS
When you deserialize an ADO.NET
DataSet from XML in the DiffGram format, null values are returned for
fabricated DataColumns whose values are computed by using aggregate functions
with expressions that reference columns in a child
DataTable. The DiffGram XML format is the default format that is used to
serialize ADO.NET
DataSet objects across process boundaries. ASP.NET Web Service and
Microsoft .NET Remoting clients might experience this behavior when they
consume (that is, deserialize) and access the data in a
DataSet that a server component serializes and returns as a DiffGram.
CAUSE
When you deserialize a
DataSet from XML in the DiffGram format, fabricated column values in a
DataTable that are computed by using columns in a child
DataTable are not recalculated.
RESOLUTION
Two workarounds are available:
- After the DataSet is returned, call the BeginEdit and the EndEdit methods on the DataTable.
- Serialize or persist the DataSet as XML without using the DiffGram format.
STATUS
Microsoft has confirmed that this is a bug in the Microsoft
products that are listed at the beginning of this article.
This bug was corrected in Microsoft ADO.NET
(included with the .NET Framework 1.1).
MORE INFORMATION
To reproduce this problem, you must complete four steps:
- Fill the DataSet with data from two tables that can be related by using a
parent-child DataRelation.
- Add a column to the parent DataTable whose value is computed by using an aggregate function that
references a column in the child DataTable.
- Serialize this DataSet object into an XML document in the DiffGram format.
- Deserialize the information from this serialized XML
document back into a DataSet.
Steps to Reproduce the Behavior
- In Microsoft Visual Studio .NET, create a new Microsoft
Visual Basic .NET Console Application project.
- Delete the existing code in Module1.vb.
- Paste the following code in Module.vb:
Note You must change User ID <username>
and password =<strong password> to the correct values before you run this
code. Make sure that User ID has the appropriate permissions to perform this
operation on the database.
Imports System.Data
Imports System.Data.SqlClient
Imports System.Xml
Module Module1
Sub Main()
Try
Dim cn As New SqlConnection _
("Server=.;Database=northwind;User Id=<username>;Password=<strong password>;")
Dim OrdersDa As New SqlDataAdapter _
("Select * from Orders where OrderId=10248", cn)
Dim OrderDetailsDa As New SqlDataAdapter _
("Select * from [Order Details]where OrderId=10248", cn)
Dim dsOrderData As New DataSet()
dsOrderData.DataSetName = "OrderData"
OrdersDa.Fill(dsOrderData, "Orders")
OrderDetailsDa.Fill(dsOrderData, "OrderDetails")
cn.Close()
Dim OrdersRelation As New DataRelation("OrderOrderDetails", _
dsOrderData.Tables("Orders").Columns("OrderID"), _
dsOrderData.Tables("OrderDetails").Columns("OrderID"))
dsOrderData.Relations.Add(OrdersRelation)
dsOrderData.Tables("Orders").Columns.Add("NumberOfItems", _
System.Type.GetType("System.Int32"), _
"COUNT(Child.ProductId)")
Dim ds As New DataSet()
'**********************************************
'Persist Dataset data in REGULAR XML format and
'read persisted data using new Dataset object.
'This method of persisting and reading correctly
'reads data values for fabricated columns.
'dsOrderData.WriteXml("OrderData.xml")
'ds.ReadXml("OrderData.xml")
'**********************************************
'**********************************************
'The following method of persisting data using
'a DiffGram format and reading persisted data using
'using a new DataSet returns null values for
'fabricated columns.
dsOrderData.WriteXml _
("OrderData.xml", XmlWriteMode.DiffGram)
dsOrderData.WriteXmlSchema("OrderSchema.xsd")
ds.ReadXmlSchema("OrderSchema.xsd")
ds.ReadXml("OrderData.xml", XmlReadMode.DiffGram)
'**********************************************
'**********************************************
'If you want to use the DiffGram format,
'you can begin an edit and
'end the edit. This will properly populate
'the DataSet.
'ds.Tables("Orders").Rows(0).BeginEdit()
'ds.Tables("Orders").Rows(0).EndEdit()
'**********************************************
If Microsoft.VisualBasic.IsDBNull _
(ds.Tables("Orders").Rows(0).Item("NumberOfItems")) Then
MsgBox("NULL - Number of Items in Order No. 10248 : " & _
ds.Tables("Orders").Rows(0).Item("NumberOfItems"))
Else
MsgBox("CORRECT - Number of Items in Order No. 10248 : " & _
ds.Tables("Orders").Rows(0).Item("NumberOfItems"))
End If
Catch exp As Exception
MsgBox("Exception Occurred : " & vbCrLf & exp.ToString)
End Try
End Sub
End Module
- Change the connection string to point to the computer that
is running Microsoft SQL Server.
- Run the code. You receive a message that the value that is
returned is a null value.
- Open the Bin folder in the sample application directory and
find the newly created OrderData.xml file.
- Open the OrderData.xml file and see if the manually
fabricated column that shows the count of the orders is correct. The line looks
similar to the following:
<NumberOfItems>3</NumberOfItems>
This shows that the column was calculated correctly and created
correctly in the .NET code, but the value is not returned correctly. Close this
XML file when you are finished.
First Workaround
- Uncomment the following lines of code:
'ds.Tables("Orders").Rows(0).BeginEdit()
'ds.Tables("Orders").Rows(0).EndEdit()
- Run the code and notice that a message box appears with the
correct number of items (three). If you again open the OrderDetails.xml file in
the Bin folder, you see that NumberOfItems contains 3, so this value is returned correctly.
Second Workaround
Create the XML file in a format other than the DiffGram format to
return the correct value.
- Comment the following blocks of code:
ds.Tables("Orders").Rows(0).BeginEdit()
ds.Tables("Orders").Rows(0).EndEdit()
dsOrderData.WriteXml _
("OrderData.xml", XmlWriteMode.DiffGram)
dsOrderData.WriteXmlSchema("OrderSchema.xsd")
ds.ReadXmlSchema("OrderSchema.xsd")
ds.ReadXml("OrderData.xml", XmlReadMode.DiffGram)
- Uncomment the following lines of code:
'dsOrderData.WriteXml("OrderData.xml")
'ds.ReadXml("OrderData.xml")
- Run the code and notice that a message box appears with the
correct number of items (three). If you again open the OrderDetails.xml file in
the Bin folder, you see that the NumberOfItems column contains 3, so this value
is returned correctly. Again, if you open the OrderData.xml file in the Bin
folder of the application directory, the NumberOfItems column is added to the
XML file and is correctly populated.
APPLIES TO
- Microsoft ADO.NET (included with the .NET Framework)
| kbfix kbbug kbpending KB325697 |
Retired KB Content DisclaimerThis article was written about products for which Microsoft no longer offers support. Therefore, this article is offered "as is" and will no longer be updated.
Community Feedback System
Very often, it takes hours to solve a problem. Very often, you've looked high
and low, and have tried a lot of solutions. When you finally found it, chances
are, it was because someone else helped you. Here's your chance to give back.
Use our community feedback tool to let others know what worked for you and what
didn't.
Please also understand that the community feedback system is not warranted to be
correct, it's simply a system that we've built to let people try and help each
other. If something in a feedback response doesn't make sense to you, or you're
not comfortable making changes that the feedback talks about (like registry
edits), please consult a professional.
Thank you for using kbAlertz.com Feedback System.
-- Scott Cate
Be the first to leave feedback, to help others about this knowledge base
article.
(Optional) Name
(Optional)
Public URL Or Email
Comments
No
HTML -- Text Only Please