Before I learned about reflection, performing object-relational mapping was a painful and slow task.
You would design your Data-Object with attributes similar to the database table it would accept data from, then there would be the long and painful process of initializing the object from the data row.
This would lead to lots of code that looked like this:
this.customerid = (int)customerRow["customerid"];
this.namefirst = (string)customerRow["namefirst"];
this.namelast = (string)customerRow["namelast"];
Which is just painful.
But, with one simple extension method, this code could be replaced by:
this.SetPropertiesFrom(customerRow);
Regardless of the number of fields, for any object...
How does it work?
Reflection allows you to examine any object's properties, methods, fields etc at run-time.
the
SetPropertiesFrom
method simply enumerates the object's public properties, and sets the value for each one that has a matching column in the data-row.
The only restriction is that the pubic properties of the object being populated must match the column names of the table. However this could be overcome by adding custom attribute decorations to the properties to indicate the source field, but that is a topic for a full article.
Here is the method in full, as an extension method for Object. Anywhere this class is in scope, each object will gain the SetPropertiesFrom method.
public static class DynamicDataExtensions
{
public static void SetPropertiesFrom(this Object obj, DataRow row)
{
foreach (PropertyInfo property in obj.GetType().GetProperties())
{
if (row.Table.Columns.Contains(property.Name))
{
DataColumn column = row.Table.Columns[property.Name];
object value = row[column];
if (!(value is DBNull))
property.SetValue(obj, Convert.ChangeType(value, property.PropertyType), null);
}
}
}
}