Introduction to the Typed DataSet
A typed DataSet is a DataSet whose data structure is known at compile time, allowing Visual Studio to create strongly typed wrappers for the tables, rows, columns, and relationships contained within the DataSet.
You can create a typed DataSet in several ways. The easiest, of course, is to use the designer provided by Visual Studio. The schema (metadata including columns, tables, keys, and relationships) for the typed DataSet is dictated using a dialect of XML called XSD (XML Schema Definition). You can also create a typed DataSet by supplying an XSD file as input to the XSD.EXE command-line tool.
In this section you'll see the various ways in which you can produce a typed DataSet and how you can use that DataSet to work with your data.
Using an XSD Schema to Create a Typed DataSet
The format and language of XSD itself is beyond the scope of this chapter. If you want to know all about the XSD standard, you can check out the XML Schema home page at http://www.w3.org/XML/Schema. The important thing to note here is that XML Schema is used for many purposes above and beyond the typing of DataSets. XML Schema has numerous uses, and Microsoft has utilized various extensions to the XSD Schema to provide additional features for typed DataSets.
Take a look at the following sample schema, which defines a table called Books that contains columns describing individual titles:
<?xml version="1.0" encoding="utf-8"?> <xs:schema xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xs:element name="Books" msdata:IsDataSet="true" msdata:UseCurrentLocale="true"> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="Book"> <xs:complexType> <xs:attribute name="id" type="xs:string" /> <xs:attribute name="author" type="xs:string" /> <xs:attribute name="title" type="xs:string" /> <xs:attribute name="price" type="xs:string" /> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> </xs:element> </xs:schema>
This schema defines the structure of a DataSet, and you can use the XSD command-line tool to create a C# class that inherits from System.Data.DataSet that provides strongly typed members specific to the preceding schema, as shown in the following code:
xsd books.xsd /d /namespace:SAMS.DataSets
This creates a class named SAMS.DataSets.Books and places it in a file named books.cs. This class inherits from System.Data.DataSet, and exposes strongly typed members on each of its rows such as id, author, title, and price. You don't need to access members using the indexer notation as in the following example:
Instead, you can use the far more friendly (and strongly typed) member accessors provided by the SAMS.DataSets.Books class:
If you don't know enough about XSD to create a schema from scratch, you can also use the XSD tool to infer a schema from an instance document. An instance document is just an XML document that contains data rather than metadata. For example, an instance document that produces the book schema is shown in the following code:
<Books> <Book author="Bob Smith" title="Life Demystified" price="99.99" /> <Book author="Joe Author" title="How to Get Rich Quick" price="8999.99" /> <Book author="Bob Author" title="Minimalism Explained, Volume 29 of 50" /> </Books>
To infer an XSD schema from your source data without having to know all of the intricacies of the XSD language, you can issue the following XSD command:
This will create the books.xsd file, which you can then use to create a typed DataSet.
Using the Designer to Build a Typed DataSet
Now that you've seen how to build a typed DataSet the "hard" way, this section will walk you through creating one visually, using the Visual Studio designer. It seems as though using raw XSD to create DataSets is not as common as it was with the first iterations of the .NET Framework and Visual Studio. In fact, support for viewing the XSD source for a DataSet created with Visual Studio has been completely removed from the product, you have to open an XSD file as if it were an XML file to get to the source view.
To get started, create any project type you like, but a console project will do just fine for this exercise. Next, right-click the project and choose Add, and then New Item. Select the DataSet template from the list of options presented to you and give it a suitable name.
You will be presented with a blank design surface onto which you can drag items from the Toolbox or even directly from the Server Explorer. This means that you can accomplish some pretty amazing things just by dragging a table from your source database onto your DataSet's design surface.
For now we'll keep it simple and just drag a DataTable onto the design surface. You can call it whatever you like. Right-click the table and choose Add, and then Column. You can choose the column name, its data type, whether it autoincrements, and much more. You can then right-click your key column and choose Set Primary Key. The interface looks and feels very much like the table creation screens in the SQL Server Management Studio application for SQL Server 2005.
Create a second table and give it a column that matches the primary key column in the first table. Drag a DataRelation from the Toolbox onto the design surface, and you can easily and visually set up a parent-child relationship between the two tables, as illustrated in Figure 20.1.
Figure 20.1. A simple DataSet with a parent table and a child table.
The design surface is an extremely powerful tool because it not only distances you from the low-level XSD generation, but it provides you with a user interface that lets you see the relationships between all of the tables in your DataSet at a quick glance, as well as the columns in each table.
Programming with a Typed DataSet
Writing code that uses typed DataSets is the easiest part of all. As you saw earlier, with a typed DataSet you don't need the string- or ordinal-based member access as shown in the following example:
Instead, you can access the members in a more user-friendly fashion because the class that derives from DataSet has exposed strongly typed members:
After you have added a DataSet to your project and configured it using the designer, you can create an instance of it and begin working with it just as you would any other DataSet. Listing 20.1 provides an illustration of how to populate a typed DataSet using its strongly typed members.
Listing 20.1. Populating a Typed DataSet Programmatically
For those of us who prefer business objects with meaningful and appropriately typed members over the generic nature of the traditional DataSet, the typed DataSet is an extremely powerful tool, providing developers with the power and flexibility of the standard DataSet coupled with the easy-to-read and easy-to-maintain strongly typed members. Using a typed DataSet's strongly typed members, you can actually catch type mismatch errors at compile time that might have otherwise taken hours or days to track down using a standard DataSet.