Channel Insider content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Typed DataSets are a common feature in .NET development projects. With the release this year of Visual Studio 2005 and the .NET Framework 2.0, how will your Typed DataSet projects fare in the upgrade process?

In this article, I discuss how the 2.0 Typed DataSets differ from the 1.x ones, and how upgrading your projects will affect your use of Typed DataSets.

While the mechanics of creating Typed DataSets are very much the same as in earlier versions of Visual Studio, the new Typed DataSets try to do much more for you.

Typed DataSets continue to work in a similar fashion to earlier incarnations, in that the designer is creates an XML Schema Document (XSD) and does code generation based on that xsd. In addition to creating the DataSet, DataTable, and DataRow derived classes, the new Typed DataSet adds a new object that is generated, called a TableAdapter. The TableAdapter’s role is to be the data access point for a single table.

There are several differences between the old version and the new. Among them are:

  • Relationships are automatically gathered from the Server Explorer.
  • A new data access object, called a TableAdapter, is created based on each of the tables.
  • You cannot view the Typed DataSet’s XSD unless you open it explicitly in the XSD or XML viewer.

Before we get too far into theory, let’s take a look at the process of adding a Typed DataSet to your application.

A Walkthrough of 2.0 Typed DataSets

To add a Typed DataSet to your project, pick “Add New Item” from the menu, as seen in Figure 1:

Figure 1: Add New Item

Then, pick “DataSet” from the Add New Dialog, as in Figure 2:

Figure 2: Adding a DataSet

Adding a new DataSet to your project gives you a new Typed DataSet design surface. To add tables to your project, you select tables, views, or stored procedures from the server explorer (as you see in Figure 3):

Figure 3: Picking Tables, Views or Stored Procs

Dragging and dropping the tables onto the design surface yields three tables, with relationships and TableAdapters, as seen in Figure 4:

Figure 4: New Typed DataSet in the Designer

Straightforward enough, right? Now let’s examine each of those features in more detail.


The purpose of TableAdapters is to simplify development. In .NET Framework 1.1, developers were often confused about how DataAdapters and DataSets worked together. By adding TableAdapters to the generated code of Typed DataSet, Microsoft hopes to end some of this confusion.

TableAdapters are constructed much like DataAdapters (see Figure 5), but they are type-safe. Interestingly, Microsoft decided that TableAdapters should not derive from DataAdapters by default. They contain a DataAdapter that does most of the work, but the DataAdapter itself is not exposed. When the TableAdapter is created, it (by default) creates GetData, Fill, and Update methods. The GetData method builds a DataTable and returns that DataTable. In contrast, the Fill method fills an existing DataTable (usually contained in a DataSet). The Update method (like DataAdapters) updates a DataRow or entire DataTable.

Figure 5: TableAdapter Properties

Within the TableAdapter is a “Query” object that you use to create the GetData and Fill methods. You can change these to specify which (or both) to create and rename the methods, as seen in Figure 6:

Figure 6: TableAdapter Query Properties

However, the problem with TableAdapters is the same as with DataAdapters. Updating a complex DataSet remains problematic, because there’s no support for smart updating based on relationships. With related data, Inserts and Updates must be performed top-down, while Deletes must be handled bottom up. TableAdapters have no support to do this, so you are left to handle this on your own. (On my own site, I offer an option of how to handle this with DataAdapters.)

Upgrading Your Typed DataSets

When you upgrade a Visual Studio .NET 2002/2003 project to Visual Studio 2005, your Typed DataSets will migrate seamlessly, for the most part. You should get the same functionality as you had previously. The nature of 1.x Typed DataSets are completely handled in Visual Studio 2005.

Upgrading the project may only be part of the change, though. To make your Typed DataSets behave more like 2.0 Typed DataSets takes a little more work.


Currently, there is no way to add TableAdapters for migrated DataTables. If you want the TableAdapter style of data access, you have to re-create your Typed DataSets. That’s because, when you drag and drop a table onto the Visual Studio 2005 designer, it stores information about the connection and SQL string used to create the TableAdapter and DataTable. Without redoing the work entirely, there is no way to generate that code.

Because this information is missing, when you try to add the TableAdapter to the DataTable, the option is unavailable, as seen in Figure 7:

Figure 7: TableAdapters are not available for Upgraded Typed DataSets

If you plan to continue to use DataAdapters, this should not be much of a hindrance. TableAdapters are more for clarity and simplification than for new functionality. TableAdapters have nearly the same feature set as DataAdapters (in fact, they are implemented using a DataAdapter), so converting to TableAdapters is definitely not required.

Customizing DataSets

Another place where Visual Studio 2005 Typed DataSet varies from Visual Studio .NET 2002/2003 is in how Typed DataSet annotations work. Annotations are used to specify specific naming and behavior changes in Typed DataSets. Using annotations was primary done by hand-editing the .xsd to include the codegen namespace. With this namespace, you could rename the plural and singular form of DataTable properties, change the way data was defaulted, and rename the accessors for getting related DataRows.

When you upgrade a project to Visual Studio 2005, these older annotations are completely supported, and your .xsd is not changed at all. (Whew.) If you make any changes to the Typed DataSet, the old annotations are replaced with new style annotations.

Yet, even though the behavior is identical, it is important to understand how these new annotations work. This is because the designer still does not support changing these code generation options directly. To get at the annotations, you need to view the Typed DataSet in an XML view. Unfortunately, they have removed the convenient XML tab from the Typed DataSet designer. You can still view it as XML, by right clicking the Typed DataSet and picking “Open With,” as seen in Figure 8:

Figure 8: Open With…

Once you select to “Open With” the Typed DataSet, you get a dialog box in which you can specify which editor to use. Choose the XML Editor, not the XSD editor, as seen in Figure 9:

Figure 9: Open With Dialog

Once you have the .xsd open in the XML editor, you will notice the new style of annotations: they all start with msprop:Generator_. There are two ways to think about the new annotations: “It is good that they include all the annotations, so I can change them without too much trouble,” or, “If I don’t use the annotations, they just muddy up my schema document.”

Upgrading your Typed DataSets does not have to be a harrowing experience. Luckily, Microsoft has taken the tack that it should be as compatible as possible. But they have not gone quite far enough, in my opinion. Hopefully, this article will help to streamline your move from Visual Studio .NET to Visual Studio 2005.

Here is a list of the annotations and what they are for. They don’t seem to be documented, so be wary of the possibility of changes in the future. In upgraded Typed DataSets, these should be used instead of the older style annotations.

Annotation (all start with ‘msprop:’) Valid On Description
Generator_UserDSName DataSet Unknown (no effect detected)
Generator_DataSetName DataSet Name of the DataSet class.
Generator_UserTableName DataTable Name of the Table accessor on DataSet
typedName DataTable Name of accessors that take the singular form. (Older form, use Generator_TableClassName instead.)
Generator_RowClassName DataTable Name of the DataRow class for that table
typedPlural DataTable Name of accessors that use the plural form
Generator_TableClassName DataTable Name of accessors that take the singular form
Generator_TableVarName DataTable Name of the variable for a table in the DataSet class
Generator_TablePropName DataTable Name of the DataSet property for that table (overrides Plural form)
Generator_RowEvArgName DataTable Name of the RowChanged Event Argument Class
Generator_RowEvHandlerName DataTable Name of the RowChanged Event Handler class
Generator_UserColumnName DataColumn Unknown (no effect detected)
Generator_ColumnVarNameInTable DataColumn Name of the local variable in the Table
Generator_ColumnPropNameInRow DataColumn Name of the property on the Row
Generator_ColumnPropNameInTable DataColumn Name of the Column property on the Table
nullValue DataColumn Specifies what is returned if the column is null. Literal value or _null or _empty are valid.
rel_typedChildren DataRelation The name of the Method to get children of a Row. (Older form, use rel_Generator_ChildPropName instead.)
rel_typedParent DataRelation The name of the property to get the parent of the Row. (Older form, use rel_Generator_ParentPropName instead.)
rel_Generator_ChildPropName DataRelation The name of the Method to get children of a Row
rel_Generator_ParentPropName DataRelation The name of the property to get the parent of the Row.