Introduction
You could use this code to transfer business objects back to tables and to do XML joins or select statements and filters on them. You could also use an XML serializer to do the same thing. Which is better, that depends. I would say this way, because you have the source, and it's really super simple, and quite fast for small tables. The XML serializer can give you some huge headaches if you have written your own collection class that supports IBindingList
. (Actually, there are known bugs in it.) If you have a very large table, you would want to use the XML serializer. (At least, I would hope that it would be more optimized than this way.)
That said, you probably should never be in a situation where you need this, but that is a whole other topic.
Let's get to it.
- Use Reflection to resolve the properties of an item in a collection.
System.Reflection.PropertyInfo [] propInfo = alist[0].GetType().GetProperties();
Now you have an array of property names (propInfo
).
- Add those properties as columns to a table:
dt.Columns.Add(propInfo[i].Name);
What we do now is get the value of the collection item property and set that into the correct row. To do that, invoke the property of the collection's item with InvokeMember
.
You will receive an object (object t
), and all you have to do is cast that to the correct type and store it in the corresponding row.
Note: This sample just uses ToString
, which may not be what you want to do because you have a string as the data type for every column. However, I just use this for creating some reports from business objects, so for that, it works perfectly.
for(int row =0;row < alist.Count ; row++)
{
dr = dt.NewRow();
for (int i=0;i< propInfo.Length;i++)
{
object tempObject =alist[row];
object t =tempObject.GetType().InvokeMember(propInfo[i].Name,
R.BindingFlags.GetProperty , null,tempObject , new object [] {});
if (t!=null)
dr[i] = t.ToString();
}
dt.Rows.Add(dr);
Complete function
Here is the complete code:
private DataTable CreateDataSource(ArrayList alist)
{
DataTable dt = new DataTable();
if (!alist[0])
throw new FormatException("Parameter ArrayList empty");
dt.TableName = alist[0].GetType().Name;
DataRow dr;
System.Reflection.PropertyInfo [] propInfo =
alist[0].GetType().GetProperties();
for(int i=0; i< propInfo.Length;i++)
{
dt.Columns.Add(propInfo[i].Name);
}
for(int row =0;row < alist.Count ; row++)
{
dr = dt.NewRow();
for (int i=0;i< propInfo.Length;i++)
{
object tempObject =alist[row];
object t =tempObject.GetType().InvokeMember(propInfo[i].Name,
R.BindingFlags.GetProperty , null,tempObject , new object [] {});
if (t!=null)
dr[i] = t.ToString();
}
dt.Rows.Add(dr);
}
return dt;
}