DaveH wrote:
When Collection.Sort didn't work, I looked for alternatives, and I considered EntityView. Like my workaround, I didn't like that making an EntityView would duplicate my existing OrderItemCollection (I really just wanted to sort it "in place").
It doesn't duplicate the collection data, it just contains indices to the entities in the collection. So if you sort a collection via its view, and then foreach over the view, you simply foreach over the collection in the order stored inside the view.
I also didn't like the idea of adding all the LLBLGenPro-specific code that would have been necessary to put (or refetch) the main entity and its prefetched child entity into an EntityView, and to sort it. (With the end result being an EntityView instead of my original collection of OrderItemEntity, unless I added even more code to project it back into an OrderItemCollection, and figure out how to repopulate its children.)
If you re-create a collection from the view, you get a new collection with the old entities. the entities aren't copies, the new collection simply references the old collection. But why bother, the view is the view to look at the collection in a sorted fashion.
If you want to, you can sort the collection's contents, but that's actually slower, simply because it has to re-arrange the inner collection's references, plus every piece of code looking at the collection sees the same ordering, which perhaps isn't what you want.
Hence my workaround to duplicate OrderItemCollection into a List<OrderItemEntity> so I could do a simple and clean list.Sort(anyComparer).
But the cleanest approach would have been to use the very intuitive OrderItemCollection.Sort(someComparer, SortDirection.Ascending) to sort the entity collection in place (like the other Sort methods, but with much more flexibility).
Note that my _natural instinct _ was to try OrderItemCollection.Sort( -- and sure enough the Collection classes do have a Sort method! But I was disappointed when I found that all 4 overloads required specifying a single field in the primary entity.
That's because they're old, left overs of the IBindingList implementation on the collections, which is now on the view.
So to sort on multiple fields, a new set of methods would have to be added, which is actually rather meaningless, as looking at a collection is actually done through a view: filtering a collection, sorting a collection, please use a view for that: the original collection stays the same, so you can create multiple views on the same collection, and the entity views implement all interfaces needed to consume the collection data anyway.
Offhand I can't think of a case where I'd ever need to provide a custom IComparer for a single int field (for example). But I can think of many uses for having multiple IComparer methods, if they were just able to compare the two entities themselves.
When comparing two entities, the comparer would have all kinds of flexibility: it could do a simple compare on a single field, but it could also compare multiple fields; calculate/derive values to be compared; and so on...all using straightforward entityName.Field syntax to get at the values to be compared.
So, you're then sorting on a calculated value, which you can also expose as a property, though you place the calculation outside the entity in a comparer? Isn't it then more a way of determining a given ordering based on the logic of the comparer and not sorting which is simply placing a set of values in ascending or descending order?