We had a fantastic VTDotNet meeting tonight with Julie Lerman presenting on ADO.NET 2.0. (The official review is in progress...) After Julie's presentation, a group of us ADO.NET-jazzed nerds were standing around talking about our experiences with ADO.NET when someone (Tom to be specific, who responded to "Gloria" in the end-of-meeting raffle to claim a new book, who I will refer to as "Virginia" to avoid confusion), mentioned that he toyed with the DataSet strong-naming functions of ADO.NET 1.x, thought it was dreadful, but had heard that it was much improved in 2.0. I don't like communicating real-time with other nerds, but I couldn't resist interrupting to mention the love I receive every day working with ADO.NET 2.0 DataSets and the new Designer, enjoying all of the benefits of 1.x strong-naming without that morning-after stiffiness, and I started talking about the new ADO.NET 2.0 TableAdapter.
"TableAdapter???" "HAA! HAA! HEE! HEE!" "Get a load of ADO.Dufus Burke talking about some ADO.NET TableAdapter! HAUUUUUGH! HAUUUUUGH!"
Well I'm back in the security of my home office, revived by the glow of the CRT and I have something to say: I'm calling you out, Virginia! I'm going to give you sucka!
This IS somewhat of a confusing point, I'll admit. Yes, there IS a new TableAdapter in ADO.NET 2.0, but it doesn't have anything to do with having intellisense for individual table columns. That is more of a function of the DataSet's [datatable]DataRow class, something which existed in ADO.NET 1.0, along with the DataSet, DataTable, and RowChangeEvent. The TableAdapter is the strongly-typed equivalent of the standard DataAdapter. You use the TableAdapter to connect to a database and execute queries or stored procedures against the database to fill an associated DataTable with data. But instead of using multiple DataAdapters to support multiple queries or commands for a single DataTable, a TableAdapter allows you to define multiple commands specific to the DataTable.
The Fill commands have friendly names, and the TableAdapter includes code to automatically fill in type and value information for all of the parameters to those command methods. No longer do you need to worry about passing in provider-specific data types like SqlInt.
Here's a simple code snippet. In Visual Studio 2003, even using a typed DataSet, the code to execute the following simple query with two parameters would be non-trivial, as in
SELECT FirstName, LastName from Employees WHERE Country = @country AND City = @city
we would have to write something like this:
Me.SqlAdapter1.SelectCommand.Parameters ("@country").value = Me.CountryListbox.SelectedValue.Trim()
Me.SqlAdapter1.SelectCommand.Parameters ("@city").value = Me.CityTextbox.Text.Trim()
Me.SqlAdapter1.Fill (Me.NorthwindDataSet.Employees)
With the TableAdapter in Visual Studio 2005, once we define the command FillByCountryAndCity, all we need to do to use it anywhere is to write one line of code, passing in the parameter values:
Me.EmployeesTableAdapter.FillByCountryAndCity ( _
Me.NorthwindDataSet.Employees, Me.CountryListbox.SelectedValue.Trim(), _ Me.CityTextbox.Text.Trim() )
So not only do we get multiple named commands from a single TableAdapter, but these commands are strongly-typed. This means that as we are writing code in Visual Studio, we get full IntelliSense to see these commands as methods of the TableAdapter. We also get compile-time type checking of the parameters to these commands, as well as the tool tip with the method and parameter type definitions.
As for the strong-typing aspects of the ADO.NET 2.0, I've blogged on this before and you can check out the comments by Steve Lasker from the ADO.NET Team which help explain the role of the TableAdapter. Here's also a good MSDN article on the new features of ADO.NET 2.0, excerpts of which I used here.
Don't push me again, Virginia. Just don't do it.