views:

118

answers:

2

Hello folks,

I've run into a problem recently, hoping you all could help.

I was tasked with creating an application that can take any DataSet, and display it in a series of grids (using something like a tab control).

I was able to do this pretty easily in WPF: 1. Create a WCF Service that returns a DataSet object 2. Create a WPF Window with a DataGrid 3. Bind the DataSet's DataTables to WPF DataGrids using AutoGenerateColumns=True

Now I have been asked to do it in Silverlight instead. So in essence, I will not know what the table will look like that I get back, so I cannot create a class with properties that can be thrown into a collection and bound. Silverlight will not allow DataSets.

I feel as if this should be a fairly common need for any platform, is there a way to handle this that doesn't require a massive amount of coding to workaround the limitations?

+1  A: 

My personal answer would be to not use DataSets (I think they're quite horrid anyway); instead make your WCF services return business objects, preferably with the help of some ORM framework (Entity Framework, NHibernate etc.) to make it easier.

Or you can use Linq to DataSet to create objects from the DataSet before sending them through WCF.

Also see these threads for more details.

Alex Paven
I don't really need to use DataSets - although they bind very nicely to WPF controls which makes life easier - but my challenge is that I do not know the structure of the set of tables coming back. They could have 3 columns, or 50. 1 row, or hundreds. This makes it difficult to create business objects when you do not know what the object may be.
enforge
It seems I posted the same link twice... the second was actually supposed to be http://forums.silverlight.net/forums/p/16309/273785.aspx (edited now the answer to include it) which does suggest another possibility. (of course, no point in waiting for dataset support in Silverlight, and there may be better solutions today in version 4, but it's a starting point).
Alex Paven
OK, let's take another approach: Forget DataSets entirely.
enforge
Oops, hitting enter posts (that was premature) ... Without DataSets, how would I pull an unknown table structure of data (columns, types and rows unknown) and bind that result to a Silverlight DataGrid?
enforge
An unknown number of rows is easy, you just return a collection of objects instead of a single object.
justin.m.chase
But what you should do is break your web service up into multiple methods. One for each different combination of possible "columns". You really SHOULD know the structure of the objects you're returning. So you should create different types of objects that represent the data you're returning from each call. If what you're doing is allowing the user to pass SQL into your webservice which returns an unknown structure of data then you're doing something very bad.
justin.m.chase
I'm not allowing them to pass in SQL, but close to that. We are going to have many different queries that each return different results. Maybe even hundreds when all is said and done. Each user will have access to any number of them based on their role. Each query will have different fields coming back.
enforge
The goal is to allow an administrator to simply add a new query to the system (top 10 X where price > Y for example) by just adding a stored procedure definition to the system. The front end should then be able to show it without needing a developer to code up an object. Does this make sense? Initially I was able to do this in few lines of code by saying new DataSet = [set of random queries], and then DataGrid = ItemsSource = DataSet.DataTable[i]. Piece of cake. The DataSet (and DataTable) were the generic business objects I needed. Now in Silverlight there is no equivalent.
enforge
A: 

One solution is to pass the DataSet Column Information and DataSet XML to the silverlight. On the Silverlight side build a Dynamic Data Object based on those data with functions provided by System.Reflection.Emit namespace. Then bind the List of dynamically build DataObject to the DataGrid. The Dynamic Data Object will have one property for each column in the DataSet with the same DataType.

Because we have the Column Information besides the Data, binding to the DataGrid can be very flexible. you can set AutoGeneratedColumn = true so it display all the Data in the DataSet or I can dynamically generate columns I want to display.

You can download the sample source code from here

Vinay B R
This sounds like it could work. Unfortunately my firm blocks personal data storage sites so right now I am unable to get to the zip file.
enforge
sorry i cant copy the source code here. try downloading it from somewhere else.
Vinay B R
Vinay, although I was not able to verify that your solution would work, it led me to another solution that may or may not be the same approach at this URL: blog.bodurov.com/…. I was able to test this successfully. Sadly, this is A LOT of code to perform what I feel is a fairly basic function (binding non-pre-defined data structures to a data grid). Considering in WPF you can handle this with about 4 lines of easy-to-read code, this is a major hole in the Silverlight architecture in my opinion
enforge