Поделиться через


Синхронизация DataSet с XmlDataDocument (ADO.NET)

Обновлен: November 2007

В этом разделе демонстрируется один шаг обработки заказа на покупку с использованием DataSet со строгой типизацией, синхронизированного с XmlDataDocument. В следующих примерах создается DataSet с минимальной схемой, соответствующей только части XML-документа источника. В примерах для точного сохранения исходного XML-документа используется объект XmlDataDocument. Это позволяет использовать объект DataSet для предоставления доступа к подмножеству XML-документа.

Следующий XML-документ содержит все сведения, относящиеся к заказу на покупку: сведения о заказчике, элементы заказа, данные для доставки и т. д.

<?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>

Один из шагов обработки сведений о заказе на покупку, содержащихся в предшествующем XML-документе, заключается в заполнении заказа на основании сведений о количестве товаров в компании. Сотруднику, ответственному за заполнение заказа на основании количества товаров на складе компании, нет необходимости видеть все содержимое заказа на покупку; ему нужно видеть только сведения о продуктах, необходимых для заказа. Чтобы из XML-документа были доступны только сведения о продуктах, создайте строго типизированный объект DataSet и со схемой XSD, которая сопоставляется с заказанными продуктами и количествами. Дополнительные сведения о строго типизированных объектах DataSet см. в разделе Типизированные объекты DataSet (ADO.NET).

В следующем коде показана схема, из которой для этого образца формируется строго типизированный объект DataSet.

<?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>

Обратите внимание, что только сведения из элементов OrderDetails и Products исходного XML-документа включаются в схему для DataSet. Синхронизация DataSet с XmlDataDocument гарантирует то, что элементы, не включенные в DataSet, будут сохраняться с XML-документом.

С DataSet со строгой типизацией, сформированным из схемы XML (с пространством имен Northwind.FillOrder), часть исходного XML-документа может предоставляться синхронизацией DataSet с XmlDataDocument, загруженным из XML-документа источника. Обратите внимание, что DataSet, сформированный из схемы, содержит структуру, но не данные. Данные заполняются при загрузке XML в XmlDataDocument. Если будет сделана попытка загрузить XmlDataDocument, синхронизированный с DataSet, уже содержащим данные, будет вызвано исключение.

После того, как DataSetXmlDataDocument) будет обновлен, XmlDataDocument может записать измененный XML-документ с неизмененными элементами, которые пропустил объект DataSet, как показано далее. В сценарии заказа на покупку после заполнения элементов заказа измененный XML-документ может быть передан на следующий шаг обработки заказа, например в отдел доставки компании.

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");
  }
}

См. также

Другие ресурсы

Синхронизация DataSet и XmlDataDocument (ADO.NET)