Typed DataSets in ADO.NET

Learn how to generate Typed DataSets in Visual Studio .NET and from the command line, as well as how to customize the generation by using annotations.

Purchase this book through the end of January and receive four exclusive sample chapters from forthcoming books by some of technology's greatest luminaries. For more information, check http://www.expectsomethingbetter.com.

This chapter is from the book

This chapter is from the book

In Chapter 5, I extolled the virtues of setting up your DataSets like in-memory
databases. Unfortunately, I asked you to write quite a bit of code to do all
the work. I was only teasing you. This chapter will show you how to use Typed
DataSets to make that job a lot easier, while at the same time creating type-safety
at compilation time.

6.1 What Are Typed DataSets?

Typed DataSets are a different animal than most of what we have discussed so
far. They are not a set of classes in the framework, but instead, they are a set
of generated classes that inherit directly from the DataSet family of classes.
Figure 6.1 contains the class diagram from Chapter 5, which shows how the
elements of the DataSet are related.

But why are they called Typed DataSets? In Chapter 5 we saw that we could
create DataColumns for our DataTables to specify what type of data could be
stored in each column. This enforces runtime type-safety, but on most occasions
we would like to know that our DataSets are type-safe when we write the code.
Typed DataSets generate classes that expose each object in a DataSet in a
type-safe manner. With a DataSet, our code would look like Listing 6.1.

We need to use indexers with the DataSet to get each piece of the hierarchy
until we finally get down to the row level. At any point you can misspell any
name and get an error when this code is executed. In addition, the last line of
the example shows us attempting to set the invoice number using a string. The
DataSet knows that this column can only hold integers so we will get a runtime
error enforcing that rule. In Listing 6.2, we do the same thing with a Typed
DataSet.

There are a few things to notice in this example. First, we create our Typed
DataSet much like we created a DataSet in the first examplethe difference
is that the schema already exists in our Typed DataSet. Second, even though this
is a Typed DataSet, the CustomerTDS class directly derives from the
DataSet class. Therefore, when we call the DataAdapters to fill our DataSet, it
will accept our Typed DataSet. In fact, the Typed DataSet is a DataSet . . . a
specialized DataSet. Next, you should notice that the syntax to get at tables
and fields is much more straightforward with Typed DataSets. Each DataTable is
now referenced with a property of CustomerTDS. Likewise, each field is
a property of a row. Not only is this syntax more straightforward, but you will
get compiler errors if you misspell any of the elements. Lastly, when we try to
set our invoice number with a string we also get a compiler error, because our
generated class knows that invoice numbers are integers.

In addition to normal columns, you can set up expression columns in our Typed
DataSets to make sure that expressions can be returned in a type-safe manner.
For instance, in the above example, we can retrieve the FullName
property from Customer. FullName is just an expression field
that puts our customer's first and last names together in a convenient
form. Because it is part of the Typed DataSet, this expression is returned as a
string.

Lastly, as we will see in this chapter, using Typed DataSets as the basis for
data object or business object layers is a powerful tool. By deriving directly
from Typed DataSets we can eliminate much of the tedium of writing these layers,
while at the same time achieving the type-safety we want.