Scenario
I need to build a table of data from a list of objects given a specification. In example, I have a list/array of Order objects, and a string specification detailing what the data table should contain e.g "ID;Date;Customer.ID;Customer.Name;Orderlines.Product.ID;Orderlines.Quantity;Orderlines.UnitPrice".
The order class class contains a list (detail) of Orderlines and the Orderline class a reference to a Product and so on. A very object oriented design by all means.
I need to create a generic procedure that takes a list of objects and a string specification and then finds all the joins. E.g AddToDataTableWithJoins(DataTable table, object[] objects, string specification).
If there exists two orders in the array, each with three orderlines the result would be a datatable with 6 rows.
e.g
{1,'2009-12-12 00:00',14,'John','DRY14',12.00,19.99}
{1,'2009-12-12 00:00',14,'John','DRY15',9.00,12.00}
{1,'2009-12-12 00:00',14,'John','DRY16',3,3.00}
{2,'2009-12-13 00:00',17,'Mike','ALR',10.00,16.00}
{2,'2009-12-13 00:00',17,'Mike','BBR',1.00,11.50}
{2,'2009-12-13 00:00',17,'Mike','PPQ',4,6.00}
But then again, the Order class may have more than one list (detail) and I must admit, that even though I'm familiar with reflection and simple recursion I'm at a loss on this on.
Any advice on how to create this algorithm is greatly appreciated.
Ideas
A restriction must be implemented so that no more than one list exists in each level of the specification, and no list exists in a different branch. e.g If the Customer class has defined a list of Order objects the following specification cannot be allowed: "ID;Date;Customer.ID;Customer.Orders.ID;Orderlines.Product.ID"
.
Then I believe, the following approach must be used:
- Determine the branch that contains one or more one-to-many relationships.
- Traverse every root object in the collection (the Order objects).
- For every property in the root object, store the values of every property not involved in the one-to-many relationships in an array.
- Use recursion and traverse every object in the child collection copying the array.
- When reaching the outermost 'node' add a new row in the DataTable.
These points may be revised as they are only thoughts at this point, but I think I'm close to something.
Thanks, Stefan