[ Team LiB ] |
Recipe 8.3 Synchronizing a DataSet with an XML DocumentProblemYou need to work with both a DataSet and its XML representation. SolutionUse a synchronized DataSet and XmlDataDocument. The sample code contains two event handlers and one method:
The C# code is shown in Example 8-5. Example 8-5. File: SyncDataSetWithXmlDocForm.cs// Namespaces, variables, and constants using System; using System.Configuration; using System.Windows.Forms; using System.Xml; using System.Data; using System.Data.SqlClient; // Table name constants private const String ORDERS_TABLE = "Orders"; private const String ORDERDETAILS_TABLE = "OrderDetails"; // Relation name constants private const String ORDERS_ORDERDETAILS_RELATION = "Orders_OrderDetails_Relation"; // Field name constants private const String ORDERID_FIELD = "OrderID"; private const String XMLFILENAME = ConfigurationSettings.AppSettings["Project_Directory"] + @"Chapter 08\Orders_OrderDetails.xml"; // . . . private void goButton_Click(object sender, System.EventArgs e) { Cursor.Current = Cursors.WaitCursor; DataSet ds = null; XmlDataDocument xmlDoc = null; if (method1RadioButton.Checked) { // Load DataSet with schema and data. ds = FillDataSet(true); // Get the XML document for the DataSet. xmlDoc = new XmlDataDocument(ds); } else if(method2RadioButton.Checked) { // Create DataSet with schema, but no data. ds = FillDataSet(false); // Get the XML document for the DataSet. xmlDoc = new XmlDataDocument(ds); // Load the data into the XML document from the XML file. xmlDoc.Load(XMLFILENAME); } else if(method3RadioButton.Checked) { // Create an XML document. xmlDoc = new XmlDataDocument( ); // Get the DataSet for the XML document. ds = xmlDoc.DataSet; // Get schema for the DataSet from the XSD inline schema. ds.ReadXmlSchema(XMLFILENAME); // Load the data into the XML document from the XML file. xmlDoc.Load(XMLFILENAME); } // Display the XML data. resultTextBox.Text = xmlDoc.OuterXml; // Bind the DataSet to the grid. dataGrid.DataSource = ds.Tables[ORDERS_TABLE].DefaultView; Cursor.Current = Cursors.Default; } private DataSet FillDataSet(bool includeData) { DataSet ds = new DataSet("Orders_OrderDetails"); SqlDataAdapter da; // Fill the Order table and add it to the DataSet. da = new SqlDataAdapter("SELECT * FROM Orders", ConfigurationSettings.AppSettings["Sql_ConnectString"]); DataTable orderTable = new DataTable(ORDERS_TABLE); da.FillSchema(orderTable, SchemaType.Source); if (includeData) da.Fill(orderTable); ds.Tables.Add(orderTable); // Fill the OrderDetails table with schema and add it to the DataSet. da = new SqlDataAdapter("SELECT * FROM [Order Details]", ConfigurationSettings.AppSettings["Sql_ConnectString"]); DataTable orderDetailTable = new DataTable(ORDERDETAILS_TABLE); da.FillSchema(orderDetailTable, SchemaType.Source); if (includeData) da.Fill(orderDetailTable); ds.Tables.Add(orderDetailTable); // Create a relation between the tables. ds.Relations.Add(ORDERS_ORDERDETAILS_RELATION, ds.Tables[ORDERS_TABLE].Columns[ORDERID_FIELD], ds.Tables[ORDERDETAILS_TABLE].Columns[ORDERID_FIELD], true); return ds; } DiscussionThe .NET Framework allows real-time, synchronous access to both a DataSet and its XML representation in an XmlDataDocument object. The synchronized DataSet and XmlDataDocument work with a single set of data. The solution shows three ways to synchronize a DataSet with an XmlDataDocument:
Example 8-6 shows the XML file used in this solution. Example 8-6. Orders with Order Details XML file, with schema<Orders_OrderDetails> <xs:schema id="Orders_OrderDetails" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xs:element name="Orders_OrderDetails" msdata:IsDataSet="true"> <xs:complexType> <xs:choice maxOccurs="unbounded"> <xs:element name="Orders"> <xs:complexType> <xs:sequence> <xs:element name="OrderID" msdata:ReadOnly="true" msdata:AutoIncrement="true" type="xs:int" /> <xs:element name="CustomerID" minOccurs="0"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:maxLength value="5" /> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="EmployeeID" type="xs:int" minOccurs="0" /> <xs:element name="OrderDate" type="xs:dateTime" minOccurs="0" /> <xs:element name="RequiredDate" type="xs:dateTime" minOccurs="0" /> <xs:element name="ShippedDate" type="xs:dateTime" minOccurs="0" /> <xs:element name="ShipVia" type="xs:int" minOccurs="0" /> <xs:element name="Freight" type="xs:decimal" minOccurs="0" /> <xs:element name="ShipName" minOccurs="0"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:maxLength value="40" /> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="ShipAddress" minOccurs="0"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:maxLength value="60" /> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="ShipCity" minOccurs="0"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:maxLength value="15" /> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="ShipRegion" minOccurs="0"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:maxLength value="15" /> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="ShipPostalCode" minOccurs="0"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:maxLength value="10" /> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="ShipCountry" minOccurs="0"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:maxLength value="15" /> </xs:restriction> </xs:simpleType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="OrderDetails"> <xs:complexType> <xs:sequence> <xs:element name="OrderID" type="xs:int" /> <xs:element name="ProductID" type="xs:int" /> <xs:element name="UnitPrice" type="xs:decimal" /> <xs:element name="Quantity" type="xs:short" /> <xs:element name="Discount" type="xs:float" /> </xs:sequence> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> <xs:unique name="Constraint1" msdata:PrimaryKey="true"> <xs:selector xpath=".//Orders" /> <xs:field xpath="OrderID" /> </xs:unique> <xs:unique name="OrderDetails_Constraint1" msdata:ConstraintName="Constraint1" msdata:PrimaryKey="true"> <xs:selector xpath=".//OrderDetails" /> <xs:field xpath="OrderID" /> <xs:field xpath="ProductID" /> </xs:unique> <xs:keyref name="Orders_OrderDetails_Relation" refer="Constraint1"> <xs:selector xpath=".//OrderDetails" /> <xs:field xpath="OrderID" /> </xs:keyref> </xs:element> </xs:schema> <Orders> <OrderID>10248</OrderID> <CustomerID>VINET</CustomerID> <EmployeeID>5</EmployeeID> <OrderDate>1996-07-04T00:00:00.0000000-04:00</OrderDate> <RequiredDate>1996-08-01T00:00:00.0000000-04:00</RequiredDate> <ShippedDate>1996-07-16T00:00:00.0000000-04:00</ShippedDate> <ShipVia>3</ShipVia> <Freight>32.38</Freight> <ShipName>Vins et alcools Chevalier</ShipName> <ShipAddress>59 rue de l'Abbaye</ShipAddress> <ShipCity>Reims</ShipCity> <ShipPostalCode>51100</ShipPostalCode> <ShipCountry>France</ShipCountry> </Orders> <Orders> <OrderID>10249</OrderID> <CustomerID>TOMSP</CustomerID> <EmployeeID>6</EmployeeID> <OrderDate>1996-07-05T00:00:00.0000000-04:00</OrderDate> <RequiredDate>1996-08-16T00:00:00.0000000-04:00</RequiredDate> <ShippedDate>1996-07-10T00:00:00.0000000-04:00</ShippedDate> <ShipVia>1</ShipVia> <Freight>11.61</Freight> <ShipName>Toms Spezialitäten</ShipName> <ShipAddress>Luisenstr. 48</ShipAddress> <ShipCity>Münster</ShipCity> <ShipPostalCode>44087</ShipPostalCode> <ShipCountry>Germany</ShipCountry> </Orders> <Orders> <OrderID>10250</OrderID> <CustomerID>HANAR</CustomerID> <EmployeeID>4</EmployeeID> <OrderDate>1996-07-08T00:00:00.0000000-04:00</OrderDate> <RequiredDate>1996-08-05T00:00:00.0000000-04:00</RequiredDate> <ShippedDate>1996-07-12T00:00:00.0000000-04:00</ShippedDate> <ShipVia>2</ShipVia> <Freight>65.83</Freight> <ShipName>Hanari Carnes</ShipName> <ShipAddress>Rua do Paço, 67</ShipAddress> <ShipCity>Rio de Janeiro</ShipCity> <ShipRegion>RJ</ShipRegion> <ShipPostalCode>05454-876</ShipPostalCode> <ShipCountry>Brazil</ShipCountry> </Orders> <OrderDetails> <OrderID>10248</OrderID> <ProductID>11</ProductID> <UnitPrice>14</UnitPrice> <Quantity>12</Quantity> <Discount>0</Discount> </OrderDetails> <OrderDetails> <OrderID>10248</OrderID> <ProductID>42</ProductID> <UnitPrice>9.8</UnitPrice> <Quantity>10</Quantity> <Discount>0</Discount> </OrderDetails> <OrderDetails> <OrderID>10248</OrderID> <ProductID>72</ProductID> <UnitPrice>34.8</UnitPrice> <Quantity>5</Quantity> <Discount>0</Discount> </OrderDetails> <OrderDetails> <OrderID>10249</OrderID> <ProductID>14</ProductID> <UnitPrice>18.6</UnitPrice> <Quantity>9</Quantity> <Discount>0</Discount> </OrderDetails> <OrderDetails> <OrderID>10249</OrderID> <ProductID>51</ProductID> <UnitPrice>42.4</UnitPrice> <Quantity>40</Quantity> <Discount>0</Discount> </OrderDetails> <OrderDetails> <OrderID>10250</OrderID> <ProductID>41</ProductID> <UnitPrice>7.7</UnitPrice> <Quantity>10</Quantity> <Discount>0</Discount> </OrderDetails> <OrderDetails> <OrderID>10250</OrderID> <ProductID>51</ProductID> <UnitPrice>42.4</UnitPrice> <Quantity>35</Quantity> <Discount>0.15</Discount> </OrderDetails> <OrderDetails> <OrderID>10250</OrderID> <ProductID>65</ProductID> <UnitPrice>16.8</UnitPrice> <Quantity>15</Quantity> <Discount>0.15</Discount> </OrderDetails> </Orders_OrderDetails> |
[ Team LiB ] |