
Introduction
Sometimes you need to populate an object (class) from a DataSet
. If you only have one record in your table then you can use serialization to populate your class. The issue comes when you have multiple records in your table. This is where serialization doesn't work as well. So using reflection you can see what is in the DataRow
and match it up with the property in your object (class). Sometimes you want to go the other way. So I also wrote an object to DataSet
conversion using reflection.
Background
We had some existing code that takes one DataRow
in a table in a dataset, puts the DataSet
into XML and then deserializes the XML into the object (class). The problem is that it only works on one record. We had the need to load hundreds of DataRow
s into objects. So instead of requesting each row and de-serializing the XML, I wrote a method that uses reflection to check what was in the DataRow
and find the matching property in the object. Note these are simple objects, i.e. there are no sub collections or arrays in them, so it is pretty much just a bunch of properties. It is a one table to one object.
Next we had a collection of objects that had been processed and needed to be written out into a DataSet
for reporting. So again I used reflection to figure out the properties and create the columns in the DataSet
table. Note these are simple objects so there isn't any processing of sub collections or arrays inside of the object. I suppose this could be a future enhancement.
Load Method
I created a Load
method that takes the list of columns in the DataRow
, the DataRow
itself and the object (class). Once the type of the object is determined then we use the InvokeMember
to reflect the DataRow
column into the property. Note it is important that the properties and the data column names match case. If the case does not match or if the column is null or if the column doesn't exist as a property, you will get an exception.
public static void Load(DataColumnCollection p_dcc,
DataRow p_dr, Object p_object)
{
Type t = p_object.GetType();
for (Int32 i=0;i<=p_dcc.Count -1;i++)
{
try
{
t.InvokeMember(p_dcc[i].ColumnName ,
BindingFlags.SetProperty , null,
p_object,
new object[] {p_dr[p_dcc[i].ColumnName]});
}
catch (Exception ex)
{
if (ex.ToString() != null)
{}
}
};
}
ObjectToTableConvert Method
Next I created an object to table conversion method. You pass in the object, and the DataSet
you want the table/DataRow
to be added to, and the table name. There is a little more going on here. First we have to check to see if the table is already in the DataSet
. If it is not then we create it and use reflection on the object to create the columns of the table. Then we use an object
array to load each of the properties of the object. Then we can load the object
array in to the table in the DataSet
.
public static void ObjectToTableConvert(Object p_obj,
ref DataSet p_ds, String p_tableName)
{
Type t = p_obj.GetType();
PropertyInfo[] tmpP = t.GetProperties();
if (p_ds.Tables[p_tableName] == null)
{
p_ds.Tables.Add(p_tableName);
foreach (PropertyInfo xtemp2 in tmpP)
{
p_ds.Tables[p_tableName].Columns.Add(xtemp2.Name,
xtemp2.PropertyType);
}
}
Object[] tmpObj = new Object[tmpP.Length];
for (Int32 i=0;i<=tmpObj.Length-1;i++)
{
tmpObj[i] = t.InvokeMember(tmpP[i].Name ,
BindingFlags.GetProperty, null,
p_obj, new object[0]);
}
p_ds.Tables[p_tableName].LoadDataRow(tmpObj,true);
}
Conclusion
There isn't a lot of code here, but I have found it helpful in converting DataRow
s to objects or objects back into tables and DataSet
s. I think this is one case where reflection works pretty well. I have included a test app that uses the Northwind SQL Server database so you can check it out for yourself.