DataSet을 XmlDataDocument와 동기화(ADO.NET)
업데이트: November 2007
이 단원에서는 XmlDataDocument와 동기화된 강력한 형식의 DataSet을 사용하여 구매 주문을 처리하는 한 가지 단계를 보여 줍니다. 다음 예제를 통해 소스 XML 문서의 일부에만 일치하는, 스키마가 최소화된 DataSet을 만듭니다. 이 예제에서는 XmlDataDocument를 사용하여 소스 XML 문서의 신뢰도를 유지하고 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 문서에서 제품 정보만 노출시키려면 XSD(XML 스키마 정의 언어) 스키마로 작성된 스키마를 사용하여 주문된 제품 및 수량에 매핑되는 강력한 형식의 DataSet을 만듭니다. 강력한 형식의 DataSet 개체에 대한 자세한 내용은 형식화된 DataSets(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>
DataSet의 스키마에는 원래 XML 문서의 OrderDetails 및 Products 요소에서 가져온 정보만 포함됩니다. DataSet을 XmlDataDocument와 동기화하면 DataSet에 포함되지 않은 요소는 XML 문서에 계속 유지됩니다.
Northwind.FillOrder 네임스페이스와 함께 XML 스키마에서 생성된 강력한 형식의 DataSet을 사용하면 DataSet을 소스 XML 문서로부터 로드한 XmlDataDocument와 동기화하여 원래 XML 문서의 일부를 노출시킬 수 있습니다. 스키마에서 생성된 DataSet에는 데이터 없이 구조만 포함됩니다. 데이터는 XML을 XmlDataDocument로 로드할 때 채워집니다. 데이터가 이미 있는 DataSet과 동기화된 XmlDataDocument를 로드하면 예외가 throw됩니다.
DataSet과 XmlDataDocument가 업데이트된 후에는 XmlDataDocument가 다음과 같이 DataSet에서 무시되어 계속해서 변경되지 않은 채 남아 있는 요소와 함께 수정된 XML 문서를 작성할 수 있습니다. 구매 주문 시나리오에서 주문 항목을 채웠으면 수정된 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");
}
}