Microsoft ADO .NET 4 Step by Step - p 14 pot

10 287 0
Microsoft ADO .NET 4 Step by Step - p 14 pot

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

Thông tin tài liệu

106 Microsoft ADO.NET 4 Step by Step Summary This chapter introduced two ADO.NET features that enhance its core functionality: aggre- gates and data views. DataTable objects support seven distinct aggregates that let you gen- erate a single value based on computing results from a single table column. Each of these seven functions—Sum, Avg, Min, Max, Count, StDev, and Var—can be used in a standalone manner to calculate a single column’s aggregate value. They can also be expressed through a table column, allowing for grouped summaries. The DataView class rolls up sorting and filtering rules for a table in a single object that in some cases can be used much like the underlying DataTable. Containing no data, the DataView includes an indexed reference to each row in the linked DataTable. Changes made to the view are reflected in the table, and vice versa. Even more important, views allow you to have two unique expressions of a single table available at the same time. Chapter 6 Quick Reference To Do This Calculate the average of a column of data Create a DataTable with valid columns and rows. Create a string containing the expression Avg(xx x), where “xxx” is the name of the column to average. Call the DataTable object’s Compute method, passing it the string expression. Find the maximum value of a child-table column associated with each row in a parent table Create parent and child DataTable objects. Add the tables to a DataSet instance. Link the tables with a DataRelation object. Create a string containing the expression Child. Max(xxx), where “xxx” is the name of the child-table column in which to locate the maximum value. Create a new DataColumn of the same data type as the examined child column. Set the DataColumn object’s Expression property to the string expression. Add the DataColumn to the parent DataTable. Generate a DataTable from a DataView Create the original DataTable. Create a new DataView instance, passing the DataTable object to its constructor. Set the DataView object’s RowFilter, Sort, and RowStateFilter properties as needed. Call the DataView object’s ToTable method, optionally indicating which columns to include. 107 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 Da taSet 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 XmlDataDocu ment 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. 108 Microsoft ADO.NET 4 Step by Step 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> Chapter 7 Saving and Restoring Data 109 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 Da taSet). 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 D ataTable 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 DataRelatio n 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) 110 Microsoft ADO.NET 4 Step by Step 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 WriteXm l 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.R eadSchema Reconstructs the DataTable members of the Da taSet without loading in the data. Chapter 7 Saving and Restoring Data 111  XmlReadMode.I gnore Schema 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. 112 Microsoft ADO.NET 4 Step by Step 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 N amespace property during object creation. Neither DataSet nor D ataColumn 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. Chapter 7 Saving and Restoring Data 113 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"> 114 Microsoft ADO.NET 4 Step by Step 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. Chapter 7 Saving and Restoring Data 115 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. . to appear as attributes for the row-level tag instead. <Customer ID="1"> 1 14 Microsoft ADO. NET 4 Step by Step This is accomplished by setting the DataColumn.ColumnMapping property. values. 112 Microsoft ADO. NET 4 Step by Step Each of these three classes includes a Namespace property, a string value containing the tar- get XML namespace name. A second property, Prefix, defines. 106 Microsoft ADO. NET 4 Step by Step Summary This chapter introduced two ADO. NET features that enhance its core functionality: aggre- gates and data views. DataTable objects support seven

Ngày đăng: 05/07/2014, 19:20

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan