Attention: We are retiring the ASP.NET Community Blogs. Learn more >

DataSets syntax

There is a good discussion about using DataSets and Customer entities here.

Even if I think DataSets is the way to go to represent database-bound data structures in .NET, there is one 'structural' thing that I don't like about DataSets (I also don't like some performance issues that will be addressed in Whidbey but that is an implementation issue and not an structural one).

When you use them for holding one instance of an entity (for example, one Customer), it's feels awkward to write:

dataSet.Customer[0].CustomerId

You don't always need to write this kind of code, because in a lot of cases you just need to bind the DataSet and let the data-binding infrastructure do its work (this is usually the case in Windows Forms), but sometimes you need to write it.

What we ended up doing in DeKlarit 3.0 is to provide the option of generating a wrapper layer on top of the DataSets that give you a better syntax, that does basically the following:

public Customer(CustomerDataSet.CustomerRow dataRow)
{
 m_DataRow = dataRow;
 m_DataSet = (CustomerDataSet) dataRow.Table.DataSet;
}

public Customer()
{
 m_DataSet = new CustomerDataSet();
 m_DataRow = m_DataSet.Customer.NewCustomerRow();   
}

public System.Int32 CustomerId
{
 get
 {
  return m_DataRow.CustomerId;
 }
 set
 {
  m_DataRow.CustomerId = value;
 }
}

We also added methods to perform persistence operation in these wrappers. For example, the 'Fill by primary key' method looks like:

public void Fill(System.Int32 customerId)
{
 DataAdapterFactory.GetCustomerDataAdapter().Fill(m_DataSet, customerId);
 m_DataRow = m_DataSet.Customer[0];
}

This means you can write:

Customer customer = new Customer();
customer.CustomerId = 1;
customer.Name = "Peter";
customer.Update();

And of course there is a 'DataSet' property that lets you access it in case you want to use it directly or bind to it.

We are also generating a 'CustomerCollection' that feels like a 'Customer' collection by wrapping a DataTable. This is the code for the indexer:

public Customer this[int index]
{
 get
 {
  return new Customer(m_DataTable[index]);
 }
 set
 {
  m_DataTable[index].ItemArray = ((Customer) value).CustomerRow.ItemArray;
 }
}

As you can see this is slighty more expensive because we copy the ItemArray when setting the row.

The CustomerCollection class has additional 'Fill' methods that load the DataTable in different ways (all the records, filtered by indexed fields, one page, etc).

Another interesting scenario is when you have a hierarchical DataSet (i.e., Order and OrderDetail). In this case we create a Order.OrderDetail class in addition to the Order class, and a Order.OrderDetailCollection class. Then you can write:

Order order = new Order();
order.Fill(100);

foreach (Order.OrderDetail detail in order.OrderDetailCollection)
{
     detail.Price = detail.Price * 1.2;
}

order.Update();


It should be easy to write a CodeSmith template that generates this code for any DataSet that has a 'tree' structure, so you can use this approach in your own DataSet-based applications.

4 Comments

Comments have been disabled for this content.