Strongly Typed DataSets in ASP.NET 2.0 Pages

One of the advanced features of ADO.NET 2.0 you can utilize from an ASP.NET page is creating and working with strongly typed DataSets. Using the DataSet class provided by the System.Data namespace, in a typical DataSet, you might access the name of a category like this:

DataRow row = categoriesDataSet.Tables["Categories"].Rows[0];
Response.Write(row["Name"]);

With strongly typed DataSets, you will be able to access your data in a much more programmer-friendly fashion:

Response.Write(categoriesDataSet.Categories[0].Name);

As you can see, the second method is much easier to understand and write. The functionality just described is made possible by a convention in the .NET Framework known as strongly typed DataSets. Strongly typed DataSets are classes that inherit from a DataSet, giving them a strongly typed nature based on an XSD structure you specify.

A typed DataSet is not a built-in member of the .NET Framework. As you will discover, it is a generated class that inherits directly from the DataSet class, and allows properties and methods to be customized from an XML schema that you specify. This class also contains other classes for DataTable and DataRow objects that are enhanced in similar ways. As a result, you can create schemas and classes for data that are customized precisely for your data, enabling you to write data access code more efficiently. Do note, however, that even though your code will be up and running more quickly, you will also be burdened eventually with keeping the structures of your strongly typed DataSets up to date as your system changes.

As you may have guessed by now, strongly typed DataSets require you to write XSD schemas. In fact, not every XSD schema qualifies to be a DataSet, so it may be argued that you need to know specifically what is allowed in an XML schema that controls what aspect of a DataSet. The good news, however, is that for a majority of your needs, Visual Studio makes it extremely easy to author strongly typed DataSets. So as you add a new DataTable, it creates and maintains an XSD schema underneath for you. In the case of strongly typed DataSets, an XML schema provides a rich definition of the data types, relationships, keys, and constraints within the data it describes. The next section provides you with a discussion on how to create strongly typed DataSets.

There are several ways to create strongly typed DataSets. This article will illustrate the creation of strongly typed DataSets in Visual Studio 2005.

Creating a Strongly Typed DataSet in Visual Studio 2005

Strongly typed DataSets are merely generic DataSets that have their columns and tables defined in advance, so the compiler already knows what they will contain. Each version of Visual Studio has made the process of strongly typing a DataSet easier, and Visual Studio 2005 has lived up to this expectation by providing an easy-to-use interface for creating and managing strongly typed DataSets. In this example, you will use the Production.Product table in the AdventureWorks database to demonstrate this feature. Simply perform the following steps:

  1. Open Visual Studio, and create a new ASP.NET web site.
  2. In Solution Explorer, right-click to add a new item, and select DataSet. Give it the name ProductDataSet.xsd. Visual Studio will recommend placing the DataSet file inside the App_Code folder, which you should allow it to do for you.
  3. The ProductDataSet.xsd will open in design mode, and the TableAdapter Configuration Wizard will be launched. For now, just click Cancel, because you will add tables by dragging them from the Server Explorer.
  4. Locate the Server Explorer Toolbox, navigate to your SQL Server 2005 database, and the AdventureWorks database.
  5. Drag the Production.Product table to your DataSet Designer window. The window should now resemble Figure 1.



Figure 1

As you can see from Figure 1, for each table that is added to the designer, Visual Studio creates a strongly typed DataTable (the name is based on the original table) and a TableAdapter. The DataTable has all of its columns already defined. The table adapter is the object you will use to fill the table. By default, you have a Fill() method that will find every row from that table.

This strongly typed DataSet, as is, will return all of the records in the Product table. Since the Product table contains a lot of information, let us modify the default query to return only the products that belong to the supplied product category. To do this, right-click the ProductTableAdapter and select Add Query. Pick Use SQL statements and click the Next button. Then, choose SELECT, which returns rows, and click Next. Finally, enter the following query in the window (or use the Query Builder to accomplish the same task):

SELECT ProductID, Name, ProductNumber, MakeFlag
FROM Production.Product
Where ProductSubcategoryID = @ProductSubcategoryID

This SQL query is a simple SELECT query with an @ProductSubcategoryID parameter to narrow down the results. This will enable you to return the products that belong to the supplied category. Leaving the Fill a DataTable and Return a DataTable check boxes checked, click Finish. After adding this SELECT statement, your designer should now have an extra query added to the ProductTableAdapter, as shown in Figure 2.



Figure 2

Note that you can also build strongly typed DataSets using a command-line utility called xsd.exe. To create the strongly typed DataSet based on the Categories.xsd schema, use the following command:

xsd /d /l:CS Categories.xsd

Now that you have created the strongly typed DataSet, the next step is to utilize it from an ASP.NET page.

Using the Strongly Typed DataSet in an ASP.NET Page

With the strongly typed DataSet created, you can easily display this data in an ASP.NET page with just a few lines of code. Listing 1 discusses the ASP.NET page that utilizes the DataSet created in the previous section.

Listing 1: Using a Strongly Typed DataSet

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data" %>
<script runat="server">
  void Page_Load(object sender, EventArgs e)
  {
    ProductDataSetTableAdapters.ProductTableAdapter adapter = new
      ProductDataSetTableAdapters.ProductTableAdapter();
    ProductDataSet.ProductDataTable table = adapter.GetDataBy(1);
    gridResults.DataSource = table;
    gridResults.DataBind();
  }
</script>
<html  >
<head id="Head1" runat="server">
  <title>Using a Strongly Typed DataSet</title>
</head>
<body>
  <form id="form1" runat="server">
    <div>
      <asp:GridView HeaderStyle-BackColor="Control"
         HeaderStyle-ForeColor="Brown"
        RowStyle-BackColor="Snow" runat="Server" ID="gridResults">
      </asp:GridView>
    </div>
  </form>
</body>
</html>

This code is very simple. You create an instance of the ProductTableAdapter, which you will use to fill the DataTable. Notice that instead of declaring a generic DataTable, you declare an object of type ProductDataTable. To fill this DataTable, you call the GetDataBy() method and pass it a category ID. Figure 3 illustrates the result of the above code sample.



Figure 3

In addition to binding the results to the GridView through code, you could also use an ObjectDataSource, setting its TypeName property to ProductDataSetTableAdapters.ProductTableAdapter and its SelectMethod to GetDataBy().

Note that strongly typed DataSets are not just limited to read-only scenarios. You can easily use strongly typed DataSets for insert, update, and delete scenarios the same way you would do with untyped DataSets.

There are additional methods to accomplish strong typing in your applications, outside of using strongly typed DataSets. For example, you can create custom classes that are more lightweight than DataSets and correspond exactly to your database.

Key Considerations for Strongly Typed DataSets

So far, you have seen examples demonstrating how strongly typed DataSets make the jobs of creating and consuming DataSets far easier. Typed DataSets are easier to maintain, have strongly typed accessors, provide rigid data validation, and, because they can still be serialized, can be exposed as the return types of web service function calls.

It would be reasonable to ask, however, whether these things are any faster or slower than regular DataSets. Unfortunately, the answer is far from clear. You may already know that throwing exceptions incurs a slight overhead from the runtime, as does typecasting. All of the properties and functions in a strongly typed DataSet are wrapped in exception-handling calls, and a great many are wrapped in typecasting code. This leads some people to believe that they are slightly less efficient than standard DataSets. However, in any production application, you’ll be wrapping your DataSet in exception-handling and typecasting code anyway, so the fact that the typed DataSet does this for you should be considered an advantage and not a performance drain.

Because of the inherent advantages of strongly typed DataSets and their role in making your code easier to develop and maintain, you should consider the feasibility of using strongly typed DataSets for your applications.

This article is adapted from Professional ASP.NET 2.0 Databases by Thiru Thangarathinam (Wrox, 2006, ISBN: 978-0-7645-9677-3), from Chapter 13, “Advanced ADO.NET for ASP.NET Data Display.”

Copyright 2007 by WROX. All rights reserved. Reproduced here by permission of the publisher.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read