Dynamic Data Access Layer, Part 1

By Anthony Jackson. Filed in C#  |  
TOP del.icio.us digg

In the article Dynamically Generate A Class From An Interface, I discussed extending what was built by having the dynamically generated class inherit off a base class that will handle not only reading data from the database to populate the class, but also updating the database.

But in order to create this class to be inherited from, we’ll need a class that is able to map between properties for a class and fields in a DataRecord.  So let’s start their:


public class Mapper<T>
{

We start simply with the Mapper class which can accept a generic T.  We then move on to creating a Map function which is able to take a single DataRecord and create an Instance Of T and return it.


protected T Map(IDataRecord record)
{
T instance = new T();

The first thing we’ll need to do is use Reflection to get information about the properties T has.  We are simply able to ask T’s Type what properties it contains:


PropertyInfo[] properties = typeof(T).GetProperties();

Now that we have a collection of PropertyInfo objects, one for each property, we’ll loop through the Fields in the DataRecord.  Unfortunately, IDataRecord does not contain an easy way to loop through using foreach, so we’ll resort to a for loop and counter.


for (int counter = 0; counter < record.FieldCount; counter++)
{

With each field we’ll make sure their is actually a value before bothering to map it.  In some cases, it is necessary to note the fact that the field is DBNull and you’ll need to modify this to handle those situations.


if (record[counter] != null &amp;&amp; record[counter] != System.DBNull.Value)
{
string fieldName = record.GetName(counter);

Next we’ll get the property which has a name that matches the field we have currently.


PropertyInfo property = typeof(T).GetProperty(fieldName);

Once we have a match between the property and field, we now will ask the property to set it’s value with the value in the current field in the current record:


if (property != null)
                    {
                        property.SetValue(instance, record[counter], null);
                    }
}
}
}

return instance;
}

That really is all we have to do.  We simply find the property and the field that have the same name and ask the property to set it’s value based on the field.  This will map a single record to a single instance of a class.

Next we need to create a method that will take a DataReader, loop through all records within it and map each individual record to an object instance.  Because this method uses the Map function to take care of the heavy lifting for each individual record, it’s actually very simple and self-explanatory:


public ObservableCollection<T> MapAll(IDataReader reader)
{
ObservableCollection<T> collection = new ObservableCollection<T>();

while (reader.Read())
{
try
{
collection.Add(Map(reader));
}
catch
{
//todo: consider handling exception here instead of re-throwing,
//graceful recovery can be accomplished
throw;
}
}

return collection;
}
}

While this class would do the job, it does have one glaring weakness.  If you were to have a 100 records being mapped into 100 objects, it would retrieve the PropertyInfo collection 100 times using Reflection.  This might be worth caching.

So this is the first step in building a Dynamic Data Layer, but it doesn’t do much on it’s own.  In Part 2 of this series (coming soon), we’ll dive into the next piece which retrieves the data from a database and uses this class to actually map it to the class.

About Anthony Jackson

Anthony Jackson has written 10 posts in this blog.

Anthony has been developing software professionally since 1996; working primarily with Microsoft technologies such as C#, VB.NET, ASP.NET and MS SQL Server. He has a varied background working in a number of industries, on teams of different sizes including Enterprise Application Development. He often takes on varied roles for projects as well, quickly adapting to what is needed for a given project and is involved in the full life-cycle of software development. This blog and it's articles are entirely the opinion of the author Anthony Jackson and do not reflect the opinions of his employers or clients past, present or future. He currently works for Avanade as a Senior System Analyst and loves working their, but everything written is still just his opinion and does not necessary reflect on any of his employers or clients past, present or future.

2 comments to “Dynamic Data Access Layer, Part 1”

TrackBacks / PingBacks

  1. Pingback
    For Versus ForEach Versus Generics With Lambda » Anthony Jackson's Software Development Blog
  2. Pingback
    Anthony Jackson's Software Development Blog » Dynamic Data Access Layer, Part 2

Leave a Reply

You must be logged in to post a comment.