Using the ADO.NET DataSet Designer
Written by Alex Armstrong   
Wednesday, 19 January 2011
Article Index
Using the ADO.NET DataSet Designer
Binding and typing
Strong Typing

 

Strong typing

Now we come to a difficult topic originally the DataSet, Table and Row objects in ADO.NET were weakly typed and all of the weakly typed methods still exist and are often used. There are strongly typed versions of each of these methods that were introduced as part of LINQ. Unfortunately the ADO.NET documentation has never been updated to reflect this new situation. So let's take a deeper look at the issue.

First what is strong typing all about?

You have gone to the trouble of setting up the structure of each Table within the DataSet by defining columns complete with names and types. This allows the compiler to know the names and types as you are writing the code. For example, the strongly typed way of accessing a value in a row is:

Row.Event = "My Birthday";

and this is possible because the strongly typed Row has an Event property which corresponds to the data field. This allows the compiler to check that the field exists, offer you Intellisense prompting and check that data types are compatible.

However you can also work with Tables that haven't been defined using the DataSet Designer and in this case the Row object is just a collection without specifically typed properties - to be more specific it is an instance of the DataRow class which doesn't know at design time the types of the columns. To access a data value in a general DataRow object you have to use collection syntax and you have to cast from object to the correct data type. For example if Row is a DataRow object:

 Row["Event"]="My Birthday";

This may seem a small change but the string is now stored as an object. If you try and retrieve it you will need a cast e.g.

String temp=(string)Row["Event"];

This is not only inconvenient it is also error prone. The compiler cannot prompt you for the field name an it cannot check data types - you have to wait to see it there is a run time error or not.

What can you do about it?

The simple answer is always use a strongly typed DataSet and always seek out the strongly typed versions of any methods you want to use.

The more complex answer is that using such strongly typed methods may take you quite a long way from basic ADO.NET. So far in fact that it is simpler to adopt LINQ as your basic approach to ADO.NET

For example the strongly typed equivalent of the ADO.NET Select isn't the corresponding LINQ Select extension method - that does a very different job. In fact it is the Where extension method and the problem is that it doesn't return an array but  an enumeration of strongly typed rows.

This simplest way of using Where is to accept what ever data type it returns and use another .NET 4 feature the anonymous type:

var rows = MyDataSet1.ImportantDates.
Where<DataSet1.ImportantDatesRow>(
         r => r.Event == "My Birthday");

Notice that as a LINQ extension method Where accepts a lambda expression. This returns an EnnumerableRowCollection (i.e. not an array) of ImportantDatesRow objects. To retrieve a particular row you would use:

string temp2 = rows.ElementAt(0).Event;

but more often than not you would probably simply process the entire collection using a for each loop.

Notice that the Where method is completely strongly typed but using it directly in this way is more difficult than simply building a LINQ query.

Perhaps the most important thing to realise is the ADO.NET is in something of a mess when it comes to various aspects of using its basic facilities. Strongly typed DataSets, Tables and Rows were introduced into ADO.NET to make it easier to use but the facilities were never really completed because the focus moved on to LINQ.

For the moment, in a world of transition, it is important that you realise that there is a distinction between strongly typed ADO.NET data and weakly typed data that simply uses the object data type and expects you to cast to the correct data type.

One short cut halfway house between the two approaches is to simply cast the row from the general DataRow class to the specific Table row class. For example:

DataSet1.ImportantDatesRow[] rows = 
(DataSet1.ImportantDatesRow[])MyDataSet1.
   ImportantDates.Select("Date>'1/1/00'");

This has the advantage of simplicity and following the cast you can work in a completely type safe way - but notice that there is always the possibility that the cast will fail it the query returns a different row structure.

However all things considered the DataSet Designer is a very easy way to create classes that wrap data base like structures in a type safe way.

 

If you would like to be informed about new articles on I Programmer you can either follow us on Twitter, on Facebook , on Digg or you can subscribe to our weekly newsletter.


<ASIN:0735648018>

<ASIN:1890774626>

Last Updated ( Wednesday, 19 January 2011 )