Sorting With Complex Business Objects
Here is a tough problem. I have an application that needs to display a lot of grids. And, of course, I am not using any System.Data.* objects, which mean that stuff like paging and sorting isn't out of the box. Paging is really easy to add, but sorting is a lot harder.
The main issue is that I don't display simple properties, but usually nested ones, or logical ones. For instnace, in a single grid, I may need to display employees details, which consist of:
Simple Properties:
- First and Last Name
Nested Properties:
- Boss's Full Name
- Department Name and ID
- Current Contract Name
Calculated Properties:
- Amount of errors in reports this month
Various views of the same data:
- Start Date - End Date
- Start Hour - End Hour
- Day of the week
Add null handling to the mix, and you get a very complex behavior. And I don't want to start writing sorting code for each and every property combination. What I really wanted to be able to do is to get access to the resolved grid data and work on that. Sure, that would have been prune to string comparision issues, but it would have been the simplest thing.
Unfortantely, while I am pretty sure that the GridView puts all its data in the ViewState, I wasn't able to find a way to get it out. So I was left with implementing sorting on my own. At the moment I have about ~160 columns that needs sorting (across 32 grids), and I have no intention of implementing sorting on a per page basis.
That left me no choice but... to write a sorting framework :-)
The requirements were pretty strict, I needed to be able to sort on anything, from a simple property to a complex expression that included multiply method calls. Just to give you a hint, here is one expression that I display:
This isn't even the most complex of them.
At first I thought about using the Dynamic Utilities from Marc, but they can't handle this kind of expressions, at least not without a lot of work. The requirements were pretty strict, anything should be sortable, including very complex expressions. And, of course, even grids that display nearly the same data will have several columns that are diffenert.
I decided that I really need to be able to make a comparision based on a full blown expression. This meant that I had to have some sort of an expression parser, which would enable me to sort by any expression at all, including complex ones like the one above. Oh, and it needs to be fast, because it is going to be used by a lot of people.
After giving it a bit of thought, I realized that I didn't need to write an expression compiler, I already had one, it is called C#. The end result? A small helper class that would generate an IComperar<T> implementations from sort expression. Now all I had left to do was:
<we:SortableTemplateField
HeaderText="Department"
SortExpression="item.Contract.At(item.Validity.Start).Department.Name">
I still had to go through all ~160 columns and add the sort expression, but that was much simpler than implementing sorting manually for all of them.
Comments
Comment preview