Synchronisieren eines DataSet mit einem XmlDataDocument (ADO.NET)

Aktualisiert: November 2007

In diesem Abschnitt wird ein Schritt bei der Verarbeitung einer Bestellung mit einem DataSet mit strikter Typbindung beschrieben, das mit einem XmlDataDocument synchronisiert wird. In den folgenden Beispielen wird ein DataSet mit einem minimalistischen Schema erstellt, das nur mit einem Teil des XML-Quelldokuments übereinstimmt. In diesen Beispielen wird ein XmlDataDocument verwendet, um das XML-Quelldokument beizubehalten, sodass das zu verwendende DataSet einen Teil des XML-Dokuments verfügbar machen kann.

Das folgende XML-Dokument enthält alle Informationen, die zu einer Bestellung gehören: Kundendaten, bestellte Ware, Lieferbedingungen usw.

<?xml version="1.0" standalone="yes"?>
<PurchaseOrder>
  <Customers>
    <CustomerID>CHOPS</CustomerID>
    <Orders>
      <OrderID>10966</OrderID>
      <OrderDetails>
        <OrderID>10966</OrderID>
        <ProductID>37</ProductID>
        <UnitPrice>26</UnitPrice>
        <Quantity>8</Quantity>
        <Discount>0</Discount>
      </OrderDetails>
      <OrderDetails>
        <OrderID>10966</OrderID>
        <ProductID>56</ProductID>
        <UnitPrice>38</UnitPrice>
        <Quantity>12</Quantity>
        <Discount>0.15</Discount>
      </OrderDetails>
      <OrderDetails>
        <OrderID>10966</OrderID>
        <ProductID>62</ProductID>
        <UnitPrice>49.3</UnitPrice>
        <Quantity>12</Quantity>
        <Discount>0.15</Discount>
      </OrderDetails>
      <CustomerID>CHOPS</CustomerID>
      <EmployeeID>4</EmployeeID>
      <OrderDate>1998-03-20T00:00:00.0000000</OrderDate>
      <RequiredDate>1998-04-17T00:00:00.0000000</RequiredDate>
      <ShippedDate>1998-04-08T00:00:00.0000000</ShippedDate>
      <ShipVia>1</ShipVia>
      <Freight>27.19</Freight>
      <ShipName>Chop-suey Chinese</ShipName>
      <ShipAddress>Hauptstr. 31</ShipAddress>
      <ShipCity>Bern</ShipCity>
      <ShipPostalCode>3012</ShipPostalCode>
      <ShipCountry>Switzerland</ShipCountry>
    </Orders>
    <CompanyName>Chop-suey Chinese</CompanyName>
    <ContactName>Yang Wang</ContactName>
    <ContactTitle>Owner</ContactTitle>
    <Address>Hauptstr. 29</Address>
    <City>Bern</City>
    <PostalCode>3012</PostalCode>
    <Country>Switzerland</Country>
    <Phone>0452-076545</Phone>
  </Customers>
  <Shippers>
    <ShipperID>1</ShipperID>
    <CompanyName>Speedy Express</CompanyName>
    <Phone>(503) 555-0100</Phone>
  </Shippers>
  <Shippers>
    <ShipperID>2</ShipperID>
    <CompanyName>United Package</CompanyName>
    <Phone>(503) 555-0101</Phone>
  </Shippers>
  <Shippers>
    <ShipperID>3</ShipperID>
    <CompanyName>Federal Shipping</CompanyName>
    <Phone>(503) 555-0102</Phone>
  </Shippers>
  <Products>
    <ProductID>37</ProductID>
    <ProductName>Gravad lax</ProductName>
    <QuantityPerUnit>12 - 500 g pkgs.</QuantityPerUnit>
    <UnitsInStock>11</UnitsInStock>
    <UnitsOnOrder>50</UnitsOnOrder>
    <ReorderLevel>25</ReorderLevel>
  </Products>
  <Products>
    <ProductID>56</ProductID>
    <ProductName>Gnocchi di nonna Alice</ProductName>
    <QuantityPerUnit>24 - 250 g pkgs.</QuantityPerUnit>
    <UnitsInStock>21</UnitsInStock>
    <UnitsOnOrder>10</UnitsOnOrder>
    <ReorderLevel>30</ReorderLevel>
  </Products>
  <Products>
    <ProductID>62</ProductID>
    <ProductName>Tarte au sucre</ProductName>
    <QuantityPerUnit>48 pies</QuantityPerUnit>
    <UnitsInStock>17</UnitsInStock>
    <UnitsOnOrder>0</UnitsOnOrder>
    <ReorderLevel>0</ReorderLevel>
  </Products>
</PurchaseOrder>

Ein Schritt bei der Verarbeitung der Bestellinformationen aus dem vorhergehenden XML-Dokument besteht darin, dass die Bestellung über den aktuellen Lagerbestand des Unternehmens ausgeführt wird. Der Mitarbeiter, der die Bestellung über das Lager des Unternehmens bearbeitet, muss nicht den gesamten Inhalt der Bestellung kennen – es genügt, wenn die Produktinformationen für die Bestellung zu sehen sind. Damit nur die Produktinformationen des XML-Dokuments verfügbar gemacht werden, erstellen Sie ein DataSet mit strikter Typbindung und einem Schema, das als XSD-Schema (XML Schema Definition Language) geschrieben wurde und den bestellten Produkten und Mengen zugeordnet ist. Weitere Informationen zu DataSet-Objekten mit strikter Typbindung finden Sie unter Typisierte 'DataSets' (ADO.NET).

Im folgenden Code wird das Schema gezeigt, aus dem das DataSet mit strikter Typbindung für dieses Beispiel generiert wird.

<?xml version="1.0" standalone="yes"?>
<xs:schema id="OrderDetail"  
                            xmlns:xs="http://www.w3.org/2001/XMLSchema" 
                            xmlns:codegen="urn:schemas-microsoft-com:xml-msprop" 
                            xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
  <xs:element name="OrderDetail" msdata:IsDataSet="true">
    <xs:complexType>
      <xs:choice maxOccurs="unbounded">
        <xs:element name="OrderDetails" codegen:typedName="LineItem" codegen:typedPlural="LineItems">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="OrderID" type="xs:int" minOccurs="0" codegen:typedName="OrderID"/>
              <xs:element name="Quantity" type="xs:short" minOccurs="0" codegen:typedName="Quantity"/>
              <xs:element name="ProductID" type="xs:int" minOccurs="0" codegen:typedName="ProductID"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="Products" codegen:typedName="Product" codegen:typedPlural="Products">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="ProductID" type="xs:int" minOccurs="0" codegen:typedName="ProductID"/>
              <xs:element name="ProductName" type="xs:string" minOccurs="0" codegen:typedName="ProductName"/>
              <xs:element name="QuantityPerUnit" type="xs:string" minOccurs="0" codegen:typedName="QuantityPerUnit"/>
              <xs:element name="UnitsInStock" type="xs:short" minOccurs="0" codegen:typedName="UnitsInStock"/>
              <xs:element name="UnitsOnOrder" type="xs:short" minOccurs="0" codegen:typedName="UnitsOnOrder"/>
              <xs:element name="ReorderLevel" type="xs:short" minOccurs="0" codegen:typedName="ReorderLevel"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:choice>
    </xs:complexType>
    <xs:unique name="Constraint1">
      <xs:selector xpath=".//Products" />
      <xs:field xpath="ProductID" />
    </xs:unique>
    <xs:keyref name="Relation1" refer="Constraint1" codegen:typedChildren="GetLineItems" codegen:typedParent="Product">
      <xs:selector xpath=".//OrderDetails" />
      <xs:field xpath="ProductID" />
    </xs:keyref>
  </xs:element>
</xs:schema>

Es werden nur Informationen aus den Elementen OrderDetails und Products des ursprünglichen XML-Dokuments in das Schema für das DataSet eingefügt. Durch die Synchronisierung des DataSet mit einem XmlDataDocument wird sichergestellt, dass die Elemente, die nicht im DataSet enthalten sind, im XML-Dokument erhalten bleiben.

Über das DataSet mit strikter Typbindung, das aus dem XML-Schema (mit dem Namespace Northwind.FillOrder) generiert wurde, kann ein Teil des ursprünglichen XML-Dokuments verfügbar gemacht werden, indem das DataSet mit dem XmlDataDocument synchronisiert wird, das aus dem XML-Quelldokument geladen wurde. Beachten Sie, dass das aus dem Schema generierte DataSet eine Struktur, aber keine Daten enthält. Die Daten werden eingefügt, wenn Sie das XML-Dokument in das XmlDataDocument laden. Wenn Sie ein XmlDataDocument laden möchten, das mit einem DataSet synchronisiert wurde, das bereits Daten enthält, wird eine Ausnahme wird ausgelöst.

Nach dem Aktualisieren des DataSet (und des XmlDataDocument) kann das XmlDataDocument – wie unten gezeigt – das geänderte XML-Dokument mit den Elementen schreiben, die von dem noch intakten DataSet ignoriert wurden. Im Bestellszenario kann das geänderte Dokument, nachdem die Posten der Bestellung angegeben wurden, an den nächsten Schritt im Bestellprozess übergeben werden; das kann z. B. die Versandabteilung des Unternehmens sein.

Imports System
Imports System.Data
Imports System.Xml
Imports Northwind.FillOrder

Public class Sample
  Public Shared Sub Main()

    Dim orderDS As OrderDetail = New OrderDetail

    Dim xmlDocument As XmlDataDocument = New XmlDataDocument(orderDS) 

    xmlDocument.Load("Order.xml")

    Dim orderItem As OrderDetail.LineItem
    Dim product As OrderDetail.Product

    For Each orderItem In orderDS.LineItems
      product = orderItem.Product

      ' Remove quantity from the current stock.
      product.UnitsInStock = CType(product.UnitsInStock - orderItem.Quantity, Short)

      ' If the remaining stock is less than the reorder level, order more.
      If ((product.UnitsInStock + product.UnitsOnOrder) < product.ReorderLevel) Then
        product.UnitsOnOrder = CType(product.UnitsOnOrder + product.ReorderLevel, Short)
      End If
    Next

    xmlDocument.Save("Order_out.xml")
  End Sub
End Class
using System;
using System.Data;
using System.Xml;
using Northwind.FillOrder;

public class Sample
{
  public static void Main()
  {
    OrderDetail orderDS = new OrderDetail(); 

    XmlDataDocument xmlDocument = new XmlDataDocument(orderDS); 

    xmlDocument.Load("Order.xml");

    foreach (OrderDetail.LineItem orderItem in orderDS.LineItems)
    {
      OrderDetail.Product product = orderItem.Product;

      // Remove quantity from the current stock.
      product.UnitsInStock = (short)(product.UnitsInStock - orderItem.Quantity);

      // If the remaining stock is less than the reorder level, order more.
      if ((product.UnitsInStock + product.UnitsOnOrder) < product.ReorderLevel)
        product.UnitsOnOrder = (short)(product.UnitsOnOrder + product.ReorderLevel);
    }

    xmlDocument.Save("Order_out.xml");
  }
}

Siehe auch

Weitere Ressourcen

Synchronisierung zwischen 'DataSet' und 'XmlDataDocument' (ADO.NET)