Demo 1: Loading a DataSet with a DataReader, Binary Serialization, and using a DataTableReader Demo Objectives Show the new serialization features of the DataSet class, including reading data from a DataReader, serializing the data in different formats to a disk file, and serializing the data in the DataSet through a DataTableReader. Demo Notes Use C# console application "dataset-features.csproj". Create a folder named Temp in the root of drive C: if you do not already have such a folder, and make sure that the account you are using to run the demo examples has permission to read and write to this folder. Demo Description This example contains four functions: GetDataReader uses a SQL batch statement to open a DataReader that exposes three rowsets. LoadDataSet then creates a new DataSet instance and loads the data from the DataReader. The automatically creates three new tables, the names of which are provided in a String array as the last parameter of the Load method. A LoadOption must be provided and the code uses OverwriteRow in this example, though the actual value makes no difference when there are no existing rows in the tables. SerializeDataSetContents takes the DataSet, a filename and a value from the SerializationFormat enumeration, and serializes the contents of the DataSet to a disk file. It is called twice, once to write the contents as XML (the default if no RemotingFormat is specified for the DataSet) and once as binary format (with DataSet.RemotingFormat = SerializationFormat.Binary). View the two disk files in Windows Explorer to see the difference in the sizes – the binary format is about one quarter of the size of the XML format file. Load them into a text editor - NOT Internet Explorer – to see the contents ReadDataSetContents creates a DataTableReader over one of the tables in the DataSet to allow it to be accessed in streaming format. The code reads the first 10 rows using the Read method of the DataTableReader and displays a coupe of the column values. Demo 2: The Stand-alone DataTable and the New Batched Updates Feature Demo Objectives Show how to create a stand-alone DataTable, and then use the batched updates feature to force updates to be performed in batches rather than one at a time. Demo Notes Use C# console application "batched-updates.csproj". NOTE: Before running the example, open SQL Profiler (from Tools menu in SQL Server Management Studio or from Start menu) and start a new trace with the default settings. Demo Description The example contains three functions that are executed in turn: GetFilledDataTable creates a stand-alone DataTable instance and uses a DataAdapter to fill it with 35 rows from the database. The code handles the new FillError event of the DataAdapter, which exposes a FillErrorEventArgs instance that contains useful information about the error, and allows the Fill process to continue with the following rows even if an error occurs for one row (by setting the Continue property). MarkRowsModified simply updates one of the columns in the row so that the row will be pushed back into the database by the Update method. It changes the ModifiedDate column to the current data and time. UpdateDatabaseRows takes the DataTable and an Integer value, and performs the update to the database. It starts by setting the UpdateBatchSize property to the Integer value provided if this is greater than zero. Then it adds a delegate (event handler) for the RowUpdated event of the DataAdapter so that it can display the batch processing. [NB: this event DOES NOT have to be handled when performing batched updates – it is done here only so that details of the batch execution can be displayed] The ContinueUpdateOnError property of the DataAdapter is set to True so that an update error won't stop the Update process, and a CommandBuilder is created to provide the auto-generated UPDATE command for the DataAdapter. Finally the Update method is called, and the result displayed showing the total number of rows affected, and the UpdateBatchSize that was used. The RowUpdated event handler simply displays details of the row that is currently being updated, the statement type, and the value of the RowCount and RowsAffected properties, all of which are exposed by the event argument instance passed to the event handler. [Now go back to SQL Profiler and stop the trace. Look for rows containing exec sp_executesql N'BEGIN... in the TextData column] In SQL Profiler, you'll see that the first update caused each row to be updated individually [statement appears in bottom window]. For the batched updates, the SQL statement that the DataAdapter generated is itself a series of exec sp_executesql stored procedure calls, one for each row in the batch. You can change the value in the Main routine for the call to the UpdateDatabaseRows routine to 0 or 1, and then run the example again, to see the difference when batched updates are not used. In this case the rows in the database are updated individually the first time, and you will see this in SQL Profiler. Demo 3: Static Create Methods and Reading Typed XML Demo Objectives To show how to use: Static Create methods and ReaderSettings classes to create an XmlReader Infer a Schema from an XML document Validate an XML document Resolve the CLR data types of the nodes in an XML document Demo Notes Use C# console application "read-write-xml.csproj". Demo Description This is a C# Console application containing four functions that are called in turn from the Main function: 1. WriteXmlDocument uses XmlWriterSettings and the Static Create method to instantiate an XmlWriter. Then it creates an XML document as a disk file by writing out elements and attributes as typed values using the WriteValue method. [writes by default into C:\Temp, create this folder or change the outDir value declared at the start of the file] 2. WriteInferedSchema uses the Inference class to infer the schema for the XML document, and then writes this schema to a disk file. 3. ReadXmlDocument is called after the Main function creates an XmlReaderSettings instance, which is passed (Along with a UTF8Encoding instance) into this function. It reads each node in turn from the XML document using an XmlReader, and displays information about the nodes. If the node has any attributes, it iterates through these displaying information about them. 4. ReadTypedXmlDocument uses the same XmlReaderSettings and UTF8Encoding, with the Static Create method to create another XmlReader instance, and then reads through the nodes in the document. This time, because the schema created earlier is specified, the values can be read as CLR types using the ReadTypedValue method. As this reads all the contents of the current element, and returns a list of values if the element contains child elements, the example restricts it to the title and reviewed "leaf node" elements (if called on the root node, it would read the whole document!) The ValueType property can then be read to get the data type of the element value. This shows that the "title" element value is a String type, but the "reviewed" element value is of type DateTime (as specified in the schema). Then, if the current node is a "slide" node, the code examines the attribute(s) of this element. It shows that the "position" attribute is of type Byte (a number) - again as specified in the schema. Demo 4: Loading, Validating and Editing with an XPathDocument Demo Objectives To show how to use: Load an XML document into an XPathDocument Edit the contents with an XPathEditableNavigator Validate the contents using the Validate and CheckValidity methods Navigate the document and edit the contents with the SetValue method Save the updated document back to a disk file Demo Notes Use C# console application "load-xpathdoc.csproj". Demo Description This is a C# Console application containing four functions that are called in turn from the Main function: 1. LoadInvalidXPathDocument loads an existing XML document from the application current folder (bin\Debug) into an XPathDocument and then creates an XPathEditableNavigator over it. A schema for the XML document is added to a new XmlSchemaSet, and this is used in the Validate method of the XPathEditableNavigator. A delegate (event handler) named CheckValid is specified in the Validate method, so this is executed each time a validation error is detected. The document contains two errors (One error in the ordering of elements and one element that contains a value that is not compatible with the specified data type). The CheckValid event handler displays information about the error. 2. LoadAndEditXPathDocument starts off the same way as the previous method, but loads an XML document that is valid and uses the CheckValidity method of the XPathEditableNavigator this time. This returns true if the document is valid, or false if not, and therefore can be used without an event handler if you don’t want to trap and see details of each error. If the XML is valid [it is in this case] the code uses the "Move" methods to move around the XML document. It extracts and displays values from the nodes as CLR types, and then uses the SetValue method write a new value into one node as a CLR type. The XML document is then saved to disk and displayed on screen.