This one crops up time and again in the business world.
The one I have used (and hate with a vengeance) was to return a DataSet or list of lists of strings with header information being in the first row. Then map column names to property types. All involve lots of code and type conversions.
A better alternative might be to return a fixed maximum number of columns (not all of them always used):
- Create a view with column1, column2... column as your variable column names (up to your maximum)
- Any common fixed columns (like primary key/id?) are added normally
Then at least you can map it across to the client statically. Basically a variable layout SQL result is best avoided if possible.
Good luck!