Home
Help
Register
Log in

Search

 
   Active Threads  

You are here: Home > LLBLGen Pro > Architecture> Sorting using an IComparer
 

Pages: 1
Architecture
Sorting using an IComparer
Page:1/1 

  Print all messages in this thread  
Poster Message
Mountain
User



Location:
Florida
Joined on:
01-Apr-2005 05:05:51
Posted:
21 posts
# Posted on: 06-Apr-2005 16:30:50.  
Why is there not a sorting method that accepts an IComparer, as in the dotnet tradition? If this is possible, it would be very helpful to us. Thanks.
  Top
John Ingram
User



Location:

Joined on:
07-Jan-2004 20:02:02
Posted:
46 posts
# Posted on: 06-Apr-2005 16:47:42.  
Mountain wrote:
Why is there not a sorting method that accepts an IComparer, as in the dotnet tradition? If this is possible, it would be very helpful to us. Thanks.


fyi

What your talking about is a in memory sort.
llbgen pro is using a database sort.


What exactly are you trying to do?


John


  Top
Otis
LLBLGen Pro Team



Location:
The Hague, The Netherlands
Joined on:
17-Aug-2003 18:00:36
Posted:
38086 posts
# Posted on: 06-Apr-2005 16:54:46.  
Mountain wrote:
Why is there not a sorting method that accepts an IComparer, as in the dotnet tradition? If this is possible, it would be very helpful to us. Thanks.

This is implemented in 1.0.2004.2 (now in beta), which has a more usable in-memory sort than the current Sort method in 1.0.2004.1.
Frans Bouma
LLBLGen Pro / ORM Profiler Lead Developer | Blog | Twitter
 
Top
Mountain
User



Location:
Florida
Joined on:
01-Apr-2005 05:05:51
Posted:
21 posts
# Posted on: 06-Apr-2005 22:26:22.  
Otis wrote:
This is implemented in 1.0.2004.2 (now in beta), which has a more usable in-memory sort than the current Sort method in 1.0.2004.1.


Thanks -- very nice.

We have IComparer methods that implement custom sorts. We couldn't seem to do the same with the existing LLBL sorts.


  Top
netLearner
User



Location:

Joined on:
18-Oct-2003 04:30:36
Posted:
150 posts
# Posted on: 07-Apr-2005 20:37:56.  
Hi Frans,
Really glad to know about the in memory sort that would be added. Can you give an example of how the code would look like for this please. I am just curious.
Thanks.
  Top
Otis
LLBLGen Pro Team



Location:
The Hague, The Netherlands
Joined on:
17-Aug-2003 18:00:36
Posted:
38086 posts
# Posted on: 07-Apr-2005 21:09:35.  
netLearner wrote:
Hi Frans,
Really glad to know about the in memory sort that would be added. Can you give an example of how the code would look like for this please. I am just curious.
Thanks.

customers.Sort("CompanyName", ListSortDirection.Descending, new CaseInsensitiveComparer());

for example, which sorts all entities on the property CompanyName descending, using a case insensitive comparer Regular Smiley. Internally values are sorted using Array.Sort() which is a quicksort implementation, and then per value the list is rebuild using a hashtable which has per value the entities with that value.



Frans Bouma
LLBLGen Pro / ORM Profiler Lead Developer | Blog | Twitter
 
Top
KevinAtClient
User



Location:

Joined on:
06-Jul-2007 21:04:24
Posted:
1 posts
# Posted on: 06-Jul-2007 21:09:42.  
In the below example, "policies" is of type PolicyStatusCollection, a class within the CollectionClasses of the BusinessEntities namespace.

policies.Sort( e.SortExpression, ListSortDirection.Ascending, new CaseInsensitiveComparer() );

This line is giving me a compiler error of the following:

Argument '3': cannot convert from 'System.Collections.CaseInsensitiveComparer' to 'System.Collections.Generic.IComparer<object>'

What gives? I don't understand why this is failing.

.....please help!
  Top
Otis
LLBLGen Pro Team



Location:
The Hague, The Netherlands
Joined on:
17-Aug-2003 18:00:36
Posted:
38086 posts
# Posted on: 10-Jul-2007 10:49:35.  
Please sort via an EntityView(2) object, so either get the DefaultView object of the collection and sort that using a normal SortExpression like you'd use on the db, or create a new entityview object.



Frans Bouma
LLBLGen Pro / ORM Profiler Lead Developer | Blog | Twitter
 
Top
DaveH
User



Location:
Tallahassee, Florida
Joined on:
01-Oct-2007 16:00:55
Posted:
6 posts
# Posted on: 01-Oct-2007 17:00:27.  
I have a similar question/request: I'd like to do an in-memory sort of a collection based on (prefetched) values in a related entity.

Some of the existing Sort overloads accept an IComparable, but they all require a single property (in the primary entity) to sort on.

If Sort had an overload that took only ListSortDirection and an IComparable (which gets passed the entities themselves instead of the values of a single property) then I would have the freedom to sort in any number of ways--from comparing just a single property in the primary entity, to examining multiple properties--even derived/custom properties in multiple related entities.

Today I work around this by creating a generic list of my LLBLGen Pro entity collection, then calling its Sort method (passing a delegate method):

Code:

TitleCollection titles = new TitleCollection();
titles.GetMulti(null);

List<TitleEntity> titlesSortedByPrice = new List<TitleEntity>(titles);
titlesSortedByPrice.Sort(TitleComparions.SortByPrice);


I'd like to be able to eliminate that step and just directly call my entity collection's Sort method:

Code:

TitleCollection titles = new TitleCollection();
titles.GetMulti(null);
titles.Sort(TitleComparions.SortByPrice, ListSortDirection.Ascending);


In each case TitleComparions.SortByPrice is passed two TitleEntity entities, and the compare method compares Price in an entity related to Title (and if Price matches, it compares Title). For simplicity this self-servicing example doesn't prefetch, but in practice I would.

--Dave
  Top
Otis
LLBLGen Pro Team



Location:
The Hague, The Netherlands
Joined on:
17-Aug-2003 18:00:36
Posted:
38086 posts
# Posted on: 12-Oct-2007 10:57:06.  
Can't you use a SortExpression for the entity view and add SortClause objects based on EntityProperty("yourpropertytosorton") ? That should work OK, also for multi-level sorts.

Frans Bouma
LLBLGen Pro / ORM Profiler Lead Developer | Blog | Twitter
 
Top
DaveH
User



Location:
Tallahassee, Florida
Joined on:
01-Oct-2007 16:00:55
Posted:
6 posts
# Posted on: 12-Oct-2007 21:51:43.  
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"). 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.)

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.

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.

Thanks,
--Dave
  Top
Otis
LLBLGen Pro Team



Location:
The Hague, The Netherlands
Joined on:
17-Aug-2003 18:00:36
Posted:
38086 posts
# Posted on: 15-Oct-2007 11:25:25.  
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.

Quote:

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.

Quote:
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.

Quote:

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?


Frans Bouma
LLBLGen Pro / ORM Profiler Lead Developer | Blog | Twitter
 
Top
Pages: 1  


Powered by HnD ©2002-2007 Solutions Design
HnD uses LLBLGen Pro

Version: 2.1.12172008 Final.