1. Trang chủ
  2. » Công Nghệ Thông Tin

Saving and Restoring Data

12 369 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Saving and restoring data
Thể loại Chapter
Định dạng
Số trang 12
Dung lượng 296,15 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Chapter 7Saving and Restoring Data After completing this chapter, you will be able to: ■ ■ Export a DataSet to a file in XML format ■ ■ Import a previously exported DataSet from XML form

Trang 1

Chapter 7

Saving and Restoring Data

After completing this chapter, you will be able to:

Export a DataSet to a file in XML format

Import a previously exported DataSet from XML format

■ Define the structure of the exported XML content

Access the XSD schema for a DataSet or DataTable

ADO.NET isn’t the only popular format for managing data in NET applications XML—content crafted using the Extensible Markup Language—is another common format that provides standardized, cross-platform data management in a semi-human-readable format

The DataSet class and the DataTable instances contained within it include features for moving

data back and forth between ADO.NET and XML This chapter demonstrates those features,

focusing on the ability to serialize the contents of a DataSet for later use, either by loading

it into another DataSet or by accessing the data directly through some other XML-enabled

application ADO.NET includes full schema definition support using Schema Definition Language (XSD)

Note Before version 4, ADO.NET included an XmlDataDocument class that supported on-demand synchronization between the contents of a DataSet and an XML document That class has

since been deprecated You can simulate some of the functionality formerly available through

XmlDataDocument using the features discussed in this chapter You can also use DataSet–focused

LINQ queries, as discussed in Chapter 18, “Using LINQ to DataSet,” as a substitute for the

obso-lete XmlDataDocument class.

Serializing DataSet and DataTable Objects

ADO.NET was designed with XML in mind, so generating XML content from a DataSet takes very little effort Reading XML content into a DataSet is even easier because ADO.NET will

guess at the correct structure of the data even if you don’t provide table design guidance

Trang 2

Writing XML

To generate XML for the data content of an existing DataSet instance, call its WriteXml method,

passing an output file name

C#

DataSet infoSet = new DataSet();

// - Add tables, relations, and data, then call

infoSet.WriteXml(@"c:\StorageFile.xml");

Visual Basic

Dim infoSet As New DataSet

' - Add tables, relations, and data, then call

infoSet.WriteXml("c:\StorageFile.xml")

In addition to file names, various overloads of WriteXml accept a valid Stream instance, a TextWriter instance, or an XmlWriter instance as their first argument The generated XML is

straightforward, using table and column names to define each element tag Here is some

typical XML data content produced by WriteXml This content includes three customer data rows, each with four fields: a string column (BusinessName), two numeric fields (ID, AnnualFee), and a date value (ContractDate) in UTC format with a time zone offset.

<CustomerDataSet>

<Customer>

<ID>1</ID>

<BusinessName>City Power &amp; Light</BusinessName>

<AnnualFee>500</AnnualFee>

<ContractDate>2008-06-01T00:00:00-07:00</ContractDate>

</Customer>

<Customer>

<ID>2</ID>

<BusinessName>Lucerne Publishing</BusinessName>

<AnnualFee>300</AnnualFee>

<ContractDate>2008-01-01T00:00:00-08:00</ContractDate>

</Customer>

<Customer>

<ID>3</ID>

<BusinessName>Southridge Video</BusinessName>

<AnnualFee>350</AnnualFee>

<ContractDate>2010-02-15T00:00:00-08:00</ContractDate>

</Customer>

</CustomerDataSet>

Trang 3

By default, WriteXml writes XML for only the data rows in each table; the method saves no information about the structure of the DataSet To include the DataSet object’s schema defi-nition along with the data, add a second argument to the WriteXml method call, passing XmlWriteMode.WriteSchema.

C#

infoSet.WriteXml(targetFile, XmlWriteMode.WriteSchema);

Visual Basic

infoSet.WriteXml(targetFile, XmlWriteMode.WriteSchema)

Other XmlWriteMode enumeration members include IgnoreSchema (don’t include the schema, which is the same as leaving off the second argument) and DiffGram (a special format that outputs differences between the Original and the Current versions of each DataRow within the DataSet).

If you want to output only the schema, use the DataSet object’s WriteXmlSchema method, passing it a file name, a Stream, a TextWriter, or an XmlWriter.

C#

infoSet.WriteXmlSchema(targetSchemaFile);

Visual Basic

infoSet.WriteXmlSchema(targetSchemaFile)

The DataTable class also includes WriteXml and WriteXmlSchema methods that you can use

to generate XML content on a table-by-table basis In addition to the file/stream/writer

tar-get and the XmlWriteMode arguments, the DataTable versions of these methods accept an optional Boolean argument that indicates whether child tables linked via DataRelation

ob-jects should be sent to the output with the instantiating table’s schema or data You can use

this Boolean argument either after or instead of the XmlWriteMode argument.

C#

// - Write the customer data AND the linked order data.

customers.WriteXml(targetFile, true);

Visual Basic

' - Write the customer data AND the linked order data.

customers.WriteXml(targetFile, True)

Trang 4

If you want to keep the XML content in the application, the DataSet class includes GetXml and GetXmlSchema methods that return string documents with content similar to the output

of the WriteXml and WriteXmlSchema methods The DataTable.GetDataTableSchema method

returns the XSD for a table in plain string format

Reading XML

Both the DataSet and DataTable classes include ReadXml and ReadXmlSchema counterparts

to the XML-writing methods To use them, create a new DataSet or DataTable instance; then call the appropriate method, passing a file name, a Stream, a TextReader, or an XmlReader.

C#

DataSet infoSet = new DataSet();

// - To read the schema, use

infoSet.ReadXmlSchema(@"c:\StorageSchemaFile.xml");

// - To read the data, use

infoSet.ReadXml(@"c:\StorageFile.xml");

Visual Basic

Dim infoSet As New DataSet

' - To read the schema, use

infoSet.ReadXmlSchema("c:\StorageSchemaFile.xml")

' - To read the data, use

infoSet.ReadXml("c:\StorageFile.xml")

A second argument to the DataSet.ReadXml method lets you indicate how the incoming

content should be processed It uses one of the following enumerated values:

XmlReadMode.Auto Lets ReadXml figure out what to do with the incoming content

automatically If it detects a valid schema with the data, it processes the schema before

loading the data If it sees a DiffGram, it interprets it appropriately This is the default

option if you don’t add the read-mode argument

XmlReadMode.ReadSchema Reconstructs the DataTable members of the DataSet

without loading in the data

Trang 5

XmlReadMode.IgnoreSchema Loads in the data, ignoring any schema that might be

included in the XML Instead, the existing DataSet structure is used.

XmlReadMode.InferSchema Builds a new schema based on the structure of the XML

data alone, ignoring any included schema If needed, any existing DataSet structure will

be augmented with new schema information

XmlReadMode.DiffGram Reads in the content previously written with the WriteXml

method’s XmlWriteMode.DiffGram mode.

XmlReadMode.Fragment Reads in and processes XML content that might be partial

or incomplete

XmlReadMode.InferTypedSchema Similar to the InferSchema mode, but ReadXml

will go out of its way to figure out the data type of each incoming data column

ReadXml or ReadXmlSchema support both inline and linked XSD structure definitions.

DataSet includes an additional InferXmlSchema method It works just like the ReadXmlSchema

method, but you can pass it an array of namespace names to exclude on import

Guiding XML Generation

The Read and Write XML methods generate valid XML that can be used right away with

any XML tools Still, the default format might be insufficient for your processing needs That’s why ADO.NET includes features that let you guide and enhance the XML generation process There are three main types of guidance you can provide to the XML content: namespace identification, child table nesting, and column management

Identifying Namespaces

XML includes a namespace feature that lets you group content by purpose, even among tags

that appear within the same parent element Three ADO.NET classes—DataSet, DataTable, and DataColumn—include properties that let you assign both the namespace and the

namespace prefix that will appear in the XML tags associated with the table and column values

Trang 6

Each of these three classes includes a Namespace property, a string value containing the tar-get XML namespace name A second property, Prefix, defines the short prefix prepended to

tag names that belong to the namespace The following code sets the namespace and prefix

for a DataTable; the process for setting these values in a DataSet or DataColumn is identical:

C#

DataTable customers = new DataTable("Customer");

customers.Namespace = "corporate";

customers.Prefix = "co";

Visual Basic

Dim customers As New DataTable("Customer")

customers.Namespace = "corporate"

customers.Prefix = "co"

The addition of the namespace and the prefix modifies the generated XML to include the

necessary xmlns attributes and prefix components.

<co:Customer xmlns:co="corporate">

<ID xmlns="corporate">1</ID>

<BusinessName xmlns="corporate">City Power &amp; Light</BusinessName>

.

Setting only the DataTable (or DataSet) namespace values applies the xmlns tag to each

contained column-related element To change these column entries to prefix-bearing tags

instead, set the Namespace and Prefix properties within each of the table’s DataColumn

objects

The constructor for the DataTable class also includes a parameter that sets the Namespace property during object creation Neither DataSet nor DataColumn includes such a parameter.

C#

DataTable customers = new DataTable("Customer", "corporate");

Visual Basic

Dim customers As New DataTable("Customer", "corporate")

The namespace and prefix settings are overridable Setting these values at the DataSet level

affects all tables within the data set except those that have their own distinct namespace

val-ues Setting the DataTable-level fields affects its columns unless you override it by setting the two properties in the DataColumn object.

Trang 7

Nesting Child Tables

By default, each table within a DataSet has its rows output at the same element level In

a data set with Customer and Order tables, each row in the Customer table would appear within the data set’s top-level XML element, followed by each row in the Order table at the same level as the Customer records Sometimes it is better to have the child table records

that belong to a parent record physically appear within their parent XML element Sample

code earlier in this chapter showed how adding an extra argument to the DataTable.WriteXml method would accomplish this But when generating XML for an entire DataSet, you must indicate your desire to nest child tables by setting the Nested property in the relevant DataRelation object.

C#

DataRelation customerOrder = new DataRelation(

customers.Columns["ID"], orders.Columns["CustomerID"]);

customerOrder.Nested = true;

Visual Basic

Dim customerOrder As New DataRelation(

customers.Columns!ID, orders.Columns!CustomerID)

customerOrder.Nested = True

Managing and Positioning Columns

As ADO.NET outputs the XML content for a DataTable, it first generates a tag for each row in

the table, using the table’s name as the containing tag Within this row tag, each column gets its own tagged element The data for each column appears as text within the column element The following content shows a single row from the “Customer” table, with subordinate tag elements for each of the four columns in the row:

<Customer>

<ID>1</ID>

<BusinessName>City Power &amp; Light</BusinessName>

<AnnualFee>500</AnnualFee>

<ContractDate>2008-06-01T00:00:00-07:00</ContractDate>

</Customer>

Sometimes you might want one or more columns to appear as attributes for the row-level tag instead

<Customer ID="1">

Trang 8

This is accomplished by setting the DataColumn.ColumnMapping property for the relevant

column object This property can be set to one of four enumerated values:

MappingType.Element The column data appears within its own XML tag element

This is the default setting for all columns

MappingType.Attribute The column value is moved into the row’s tag and stored as

an XML attribute

MappingType.SimpleContent The data for this column becomes the entire content

for the row’s tag element Only one column within a table can be designated as the

SimpleContent column All other columns must either be set as attributes or must be

hidden

Note Setting a column’s mapping type to SimpleContent will generate an exception if any other columns in the same table have a mapping type of Element or SimpleContent.

MappingType.Hidden This column is excluded from the generated XML content.

In addition to setting the ColumnMapping property, the constructor for the DataColumn

ob-ject lets you define the mapping type

C#

DataColumn orderID = new DataColumn("ID", typeof(int), MappingType.Attribute);

Visual Basic

Dim orderID As New DataColumn("ID", GetType(Integer), MappingType.Attribute)

Generating XML from a DataSet: C#

1 Open the “Chapter 7 CSharp” project from the installed samples folder The project

in-cludes one Windows.Forms class named Serialization.

2 Open the source code view for the Serialization form Locate the ActGenerate_Click

function This routine produces the XML content from a sample DataSet containing two tables: Customer and Order.

3 Just after the “Set the XML namespace” comment, add the following statements:

SampleDataSet.Tables["Customer"].Namespace = TableNamespace.Text.Trim();

SampleDataSet.Tables["Customer"].Prefix = TablePrefix.Text.Trim();

SampleDataSet.Tables["Order"].Namespace = TableNamespace.Text.Trim();

SampleDataSet.Tables["Order"].Prefix = TablePrefix.Text.Trim();

This code sets the namespace and prefix values for both of the sample tables

Trang 9

Note As mentioned in the chapter discussion, you can also define namespace and prefix

val-ues within each DataColumn Although it is not included in the sample code, consider adding

code that will loop through all columns in each of the two tables and add the user-specified namespace and prefix values.

4 Just after the “Indicate the relationship type” comment, add the following line:

SampleDataSet.Relations[0].Nested = NestChildRecords.Checked;

This statement determines whether the order rows for each customer record are

con-tained within the <Customer> tag (true) or whether all <Order> tags appear after and

at the same level as all the <Customer> tags in the XML (false).

5 Just after the “Build a memory stream to hold the results” comment, add the following

code:

holdBuffer = new MemoryStream(8192);

SampleDataSet.WriteXml(holdBuffer,

(XmlWriteMode)OutputWriteMode.SelectedItem);

These lines perform the actual XML generation, sending the results to a stream, in this

case a MemoryStream instance The remaining code in the event handler moves the

XML content from the stream to an on-form text box

6 Run the program Use the fields in the upper-right corner of the form to alter the XML

content and then click Generate to produce the XML As an example, set the XML Write

Mode to WriteSchema, change the Mapping for both Parent.ID and Child.ID to Attribute, and set the Mapping for Child.CustomerID to Hidden Click Generate The

XML will contain the XSD schema for the data set, followed by distinct <Customer> and

<Order> elements.

Trang 10

Generating XML from a DataSet: Visual Basic

1 Open the “Chapter 7 VB” project from the installed samples folder The project includes

one Windows.Forms class named Serialization.

2 Open the source code view for the Serialization form Locate the ActGenerate_Click

function This routine produces the XML content from a sample DataSet containing two tables: Customer and Order.

3 Just after the “Set the XML namespace” comment, add the following statements:

SampleDataSet.Tables("Customer").Namespace = TableNamespace.Text.Trim

SampleDataSet.Tables("Customer").Prefix = TablePrefix.Text.Trim

SampleDataSet.Tables("Order").Namespace = TableNamespace.Text.Trim

SampleDataSet.Tables("Order").Prefix = TablePrefix.Text.Trim

This code sets the namespace and prefix values for both of the sample tables

Note As mentioned in the chapter discussion, you can also define namespace and prefix

val-ues within each DataColumn Although it is not included in the sample code, consider adding

code that will loop through all columns in each of the two tables and add the user-specified namespace and prefix values.

4 Just after the “Indicate the relationship type” comment, add the following line:

SampleDataSet.Relations(0).Nested = NestChildRecords.Checked

This statement determines whether the order rows for each customer record are

con-tained within the <Customer> tag (True) or whether all <Order> tags appear after and

at the same level as all the <Customer> tags in the XML (False).

5 Just after the “Build a memory stream to hold the results” comment, add the following

code:

holdBuffer = New MemoryStream(8192)

SampleDataSet.WriteXml(holdBuffer,

CType(OutputWriteMode.SelectedItem, XmlWriteMode))

These lines perform the actual XML generation, sending the results to a stream, in this

case a MemoryStream instance The remaining code in the event handler moves the

XML content from the stream to an on-form text box

Ngày đăng: 03/10/2013, 00:20

TỪ KHÓA LIÊN QUAN

w