Converting an object collection to a DataSet
There are many tools that tends to work only with DataSets, the most often cases are reporting tools or data driven systems. I consider this an issue with the tool, usually, but this is a fact of line. Case in point, I want to display a report of customer objects, I say objects here because I retrieve them through an NHibernate query + business logic that can't really be done in a stored procedure.
At the end, I get a collection of customer objects, and I need to pass that to a reporting tool that can only accept a DataSet, this means that I need to translate an object graph to tabular format.
Here is my secret technique to do this:
DataTable dt = new DataTable();
dt.Columns.Add("CustomerId", typeof(int));
dt.Columns.Add("CustomerName", typeof(string));
dt.Columns.Add("RegisteredAt", typeof(string));//not a typo, sadly.
// ... lot more properties, often nested ones.
foreach(Customer cust in customers)
{
DataRow row = dt.NewRow();
row["CustomerId"] = cust.Id;
row["CustomerName"] = cust.At(reportDate).Name;
row["RegisteredAt"] = cust.RegisteredAt.ToShortDateString();
//... lot more properties
dt.Rows.Add(row);
}
DataSet ds = new DataSet();
ds.Tables.Add(dt);
return ds;
Sorry that it isn't magic, just the simplest solution that could work without writing a whole new data source adapter for the tool.
Comments
Simply perfect! ;o)
"Do the simplest thing that could possibly work" [Kent Beck]
I am wondering what reporting tool are you using? If you are building on top of.Net 2.0+, anything that you pass the DataSet to you should be able to pass BindingList<T>. Then the code could just be:
BindingList<Customer> boundCustomers = new BindingList<Customer>(customers);
return boundCustomers;
That is not possible because I need to talk to a Reporting Service that calls me via web service, while I may be able to hand the data directly to a local instance, in this case, they are two distinct application, on different servers.
I have used this code in projects before. Sorry for the bad code formatting I am still a little new to this blog thing.
http://abombss.wordpress.com/2007/05/09/nhibernate-to-dataset/
I have used XML Serialization in the past for a similar situation but I am not sure if it would be a good fit for you or which would perform better.
I was also going to suggest that you could serialize the objects to xml then load them into the dataset. this would save you from having to do a bunch of property assignment. Would also lessing the chance of breakage do to coding changes.
Not sure if it would work though.
Derik
Not going to work, I am also doing some flattening of the data, so it is actually something like:
row["MotherMaidenName"] = customer.Mother.Maiden.Name;
Why didn't you go for a projection engine for nhibernate instead? It shouldn't take that long to write and it then gives you the ability to project any graph to datasets/tables etc. (took me about a week or so for llblgen)
the fun thing is that you then could put that engine to work for projecting entity graphs onto webservice message objects for example (object-document mapping)
Btw, good luck next week in Montreal with the ORM Smackdown against Ted 'I-don't-like-orm' Neward :D
Frans,
I didn't do it because I needed it for ~4 reports. Wasn't worth the time to invest in it.
Thanks.
For converting object lists into datasets we've written a simple class, which would put required properties (even nested ones) into a new datatable.
why write so many code :)
I'm sure I'm missing somthing big here because I don't see anyything worth the Ayendes blog in the post about how to iterrate through collection and put the collection members in the data set rows
So, what I'm missing? :)
That you don't always need a super smart framework to do this kind of things.
People asked how I am doing it, this is stupid code, very simple, one purpose only. It is used for something that I need once every blue moon, so I just wrote it instead of building a framework.
In other words, this is a post about "no magic involved"
I think have the same problem with grid controls (radGrid, ms grid etc.)
NHibernate does a great job of getting me a List of Orders (with a property for a collection of OrderItems). While I can bind the Orders to a Grid, when I wat a second level nested table for the OrderItems I cannot do this. Despite this feeling natural to me. I am now thinking I need to start looking at DataSets to do this, unless any of you cna think of other options?
Thanks
Writing your own grid :-)
I don't kid, BTW.
A simple option is nested repeaters
Comment preview