Indexers, are one of the ugliest methods of accessing Data stored in objects, they do not lend them selves to the eye, and using DataSet’s you will find yourself using the indexers a lot, below is a line of code showing the use of Indexers in a DataSet.
string myFooRegistration = myDataSet.Tables[0].Rows[1][2].ToString();
The above does not seem particularly elegant in comparison to a Strongly typed object such as the one shown below which only exhibits one indexer to achieve the same: -
string myFooRegistration = Foos[1].Registration;
In the same vein, it is possible to make your Collection Indexer’s even more Developer friendly by using Strings or any other Data Type as your indexing identifier, for example below a string (Foo Registration) is used as the indexer: -
string myFooRegistration = Foos[“DMN 666”].RegistrationDate;
Weakly Typed fields in DataSet’s lead to confusion and can very easily end up with people using the wrong Type for the Data that is being represented. It’s much more difficult to get a number out of a DataSet than it is to get a number out of a Strongly Typed object.
int myFooId = ((int)myDataSet.Tables[0].Rows[1][0].ToString());
In comparison to: -
int myFooId = Foos[1].Id;
Knowledge of the Data Structure, developers need to know the structure/schema of the Data stored within DataSet’s to get the best out of them, and DataSet’s do not lend them selves to this aim, however when using Strongly Typed Objects your Data Structure is already mapped out in Properties and Methods on your objects.
As a Developer using a DataSet you need to know what the field names are called exactly or at which index in your DataRow’s the field you are looking for can be found: -
int myFooId = ((int)myDataSet.Tables[0].Rows[1][0].ToString());
int myFooId = ((int)myDataSet.Tables[0].Rows[1][“Id”].ToString());
The above is acceptable if there will only be one developer working with the code (a personal project for example), however in a team environment Developers find code that takes the responsibility away from them understanding and knowing the Data Schema much easier to work with.
Special Methods, cannot be added to your DataSet’s easily, however using Strongly Typed objects it is possible to have methods sitting inside your objects that can expose business logic, for example using the Strongly Typed Foo object we can perform actions that would with DataSet’s be a separate method call: -
Foos[1].SubmitToQA();
This kind of functionality is even more useful when thinking about Collections of objects, for example you may want to do some filtering on the Foos Collection, you may need to know what the Minimum and Maximum Price’s of the Objects in the Collection are, you’d just add two properties to the FooCollection class as so -
double MinimumPrice = Foos.MinimumPrice;
double MaximumPrice = Foos.MaximumPrice;
Strongly Typed Objects within Strongly Typed Objects, are very easy to create and use, and again they follow the Data Structure issues that have been mentioned above. Taking our Foo object again, we’ll look at a sample of this functionality.
int myDerivativeId = myFoo.Derivative.Id;
But even nicer than the above is the ability to have Collections within your objects, so you might have something like this: -
string myOptionName = myFoo.Options[0].Name;
Or Even: -
foreach(Option O in myFoo.Options)
{
Response.Write(O.Name + “<br />”);
}
Data Binding, is just as easy with Strongly Typed Objects as it is with DataSet’s. And in some cases it’s much easier, for example the Fields you need are all available in strongly typed names, and when you’re working with VS.NET with inline Code there is no Intellisense to help you out, friendly names are much more helpful. The Code Behind methods of Data Binding work as normal: -
Foos.DataSource = myFoos; //myFoos is of type FooCollection
Foos.DataBind();
Your inline Data Binding code is also the same: -
<asp:Repeater ID="Foos" Runat="server">
<ItemTemplate>
<SPAN class="body">Title: <%# DataBinder.Eval(Container.DataItem,"Title") %></SPAN><br />
<SPAN class="body">Mileage: <%# DataBinder.Eval(Container.DataItem,"Miles","{0:N0}") %></SPAN<br />
<SPAN class="body">Price: <%# DataBinder.Eval(Container.DataItem,"Price","{0:C0}") %></SPAN><br />
</ItemTemplate>
</asp:Repeater>
You can even access your Strongly Typed objects where normally you would have to use ItemArray’s: -
private void Foos_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e)
{
BusinessObjects.Foo myFoo = new BusinessObjects.Foo();
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem )
{
myFoo = ( ( BusinessObjects.Foo ) e.Item.DataItem );
}
System.Web.UI.HtmlControls.HtmlGenericControl PriceChangeSection = ((System.Web.UI.HtmlControls.HtmlGenericControl )e.Item.FindControl("PriceDifferenceSpan"));
if (PriceChangeSection != null)
{
if (myFoo.OldPrice > 0)
{
PriceChangeSection.Visible = true;
}
else
{
PriceChangeSection.Visible = false;
}
}
}
Unit Testing, is very simple using Strongly Typed Objects, you can create them in code, you don’t need a Database to be in place to retrieve Data from, and you can test your Business Logic in the same place as you’re testing your Data Structure.