Default sort on collection

Posts   
 
    
Posts: 1268
Joined: 10-Mar-2006
# Posted on: 14-Sep-2006 21:38:21   

Using selfservicing, you can set the default sort on a related field collection using SetCollectionParameters[relatedfield].


MyEntity myEntity = new MyEntity();
myEntity.SetCollectionParametersRelatedField(0, <somesort>);
myEntity....fetch...etc

However, I want that sort to be the default for every MyEntity constructed.


MyEntity myEntity = new MyEntity();  //sort already set up
myEntity....fetch...etc

I tried override to place code in OnInitializing(), but that gives an error as everything is not setup yet?

I then did an override of OnInitialized() and that seems to work.

However, if you retrieve an entity using a PreFetchPath when newing the object, the fetch is performed before OnInitialized() is called, so the sort is not done.

Where should I put this?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 14-Sep-2006 22:21:36   

What error did you get when you overrided OnInitializing ?

Frans Bouma | Lead developer LLBLGen Pro
Posts: 1268
Joined: 10-Mar-2006
# Posted on: 15-Sep-2006 04:24:32   

Get error on these lines - _message is not assigned. "Object reference not set to an instance of an object"

public virtual void SetCollectionParametersMessage(long maxNumberOfItemsToReturn, ISortExpression sortClauses) { _message.SortClauses=sortClauses; //Error on this line _message.MaxNumberOfItemsToReturn=maxNumberOfItemsToReturn; }

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 15-Sep-2006 08:10:50   

Try to put your code in the following user code region

// __LLBLGENPRO_USER_CODE_REGION_START InitClassMembers
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 15-Sep-2006 09:40:55   

... which you can fill with an include template simple_smile

Indeed InitClassMembers isn't called yet when OnInitializing is called, you then indeed need OnInitialized. However I don't follow why that would be too late in the case of a prefetchpath.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 1268
Joined: 10-Mar-2006
# Posted on: 15-Sep-2006 15:59:21   

Walaa wrote:

Try to put your code in the following user code region

// __LLBLGENPRO_USER_CODE_REGION_START InitClassMembers

Ugh....I am using the 2 class scenario, so I am not modifying the code in the base classes. Also, in the derrived class, I am trying to keep all modifications in partial classes so I know and can easily find my custom code. That makes this solution less than ideal.

However, if InitClassMembers() were made virtual, then I could simply override it. Think this can be done in the future?

Otis wrote:

... which you can fill with an include template simple_smile

I looked at the template that generates this code (entityInclude.template) and there is only one include template - "Custom_EntityInitializationTemplate" which is not in the right place in the template. Am I missing something?

Otis wrote:

Indeed InitClassMembers isn't called yet when OnInitializing is called, you then indeed need OnInitialized. However I don't follow why that would be too late in the case of a prefetchpath.

If you construct an entity with a prefetch path, that constructor calls this code. You will see that the data is already fetched, using the prefetch path - your related data is fetched also - and then at the end, OnInitialized() is called

        protected virtual void InitClassFetch(System.Int32 messageThreadId, IValidator validator, IPrefetchPath prefetchPathToUse)
        {
            OnInitializing();
            InitClassMembers();

            base.Fields = CreateFields();
            bool wasSuccesful = Fetch(messageThreadId, prefetchPathToUse, null);
            base.IsNew = !wasSuccesful;
            base.Validator = validator;

            
            // __LLBLGENPRO_USER_CODE_REGION_START InitClassFetch
            // __LLBLGENPRO_USER_CODE_REGION_END
            

            OnInitialized();
        }
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 15-Sep-2006 17:28:56   

WayneBrantley wrote:

[

Otis wrote:

Indeed InitClassMembers isn't called yet when OnInitializing is called, you then indeed need OnInitialized. However I don't follow why that would be too late in the case of a prefetchpath.

If you construct an entity with a prefetch path, that constructor calls this code. You will see that the data is already fetched, using the prefetch path - your related data is fetched also - and then at the end, OnInitialized() is called

        protected virtual void InitClassFetch(System.Int32 messageThreadId, IValidator validator, IPrefetchPath prefetchPathToUse)
        {
            OnInitializing();
            InitClassMembers();

            base.Fields = CreateFields();
            bool wasSuccesful = Fetch(messageThreadId, prefetchPathToUse, null);
            base.IsNew = !wasSuccesful;
            base.Validator = validator;

            
            // __LLBLGENPRO_USER_CODE_REGION_START InitClassFetch
            // __LLBLGENPRO_USER_CODE_REGION_END
            

            OnInitialized();
        }

Ah in the case where you fetch a SINGLE entity with a prefetch path? I thought you meant when yuo were fetching entities with a prefetch path, like customers, their orders etc. and the collections in orders weren't settable because of this.

Also, OnInitialized, is called when an entity is instantiated, so when you do: CustomerEntity c = new CustomerEntity(); // the OnInitialized method is now called, collections are now setup. c.FetchUsingPK(... );

it should work ok.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 1268
Joined: 10-Mar-2006
# Posted on: 16-Sep-2006 02:39:28   

Also, OnInitialized, is called when an entity is instantiated, so when you do: CustomerEntity c = new CustomerEntity(); // the OnInitialized method is now called, collections are now setup. c.FetchUsingPK(... );

it should work ok.

Yeah, but I dont want to have an entity that has methods that dont work! Would it be possible to just have the InitClassMembers() made virtual?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 16-Sep-2006 19:28:44   

I'm sorry, but there's always a given order in which these things have to happen. I can't design it for very possible scenario out there. The initclassmembers is a private method, so I can't make it virtual.

The methods DO work btw rage but in THIS particular scenario there's an ORDER in which things have to happen, and that's unfortunately, not suiting YOUR situation

Frans Bouma | Lead developer LLBLGen Pro
Posts: 1268
Joined: 10-Mar-2006
# Posted on: 19-Sep-2006 19:31:23   

The methods DO work btw but in THIS particular scenario there's an ORDER in which things have to happen, and that's unfortunately, not suiting YOUR situation

I did not mean to imply YOUR methods do not work cry - Given the 'order problem' there would be certain ways to construct the object that would cause my code not to work (because the sort order is wrong) and other ways where it would work fine. That seems very bad, so would seem better to just place the sorting code everywhere throughout the project.

I might be the only one (wouldn't be the first time) one who wants to preset the order the collections are sorted in with my custom class! Does everyone else sets them everytime the use the object throughout all systems?

In fact, I have often thought of a 'feature request' - being able to choose which fields are sorted and asc/desc in the designer - then it could be generated right into the object. I was even considering doing an add-on using custom properties to make this happen, but it seems I cannot without modifying the shipping templates...

Is this feature on your feature request list?

... which you can fill with an include template

I could not find such a template place?

Don't get me wrong, I understand your position, but I am still trying to find a good answer! Normally, I can do anything I want by using a derrived class - but in this case I could not and was hoping for some answer/change to help me?

The initclassmembers is a private method, so I can't make it virtual.

Perhaps that is the wrong 'request' then. Would you consider another change/hook into the base classes that would let me do this? I guess I could put some code into the "InitClassMembers" user code region. However, was thinking a virtual method called from the end of InitClassMembers() - "InitedClassMembers" or something would be good - so I dont have code placed in user code regions everywhere. With partial classes, I had hoped to not need/use user code regions anymore.

Any considerations would be appreciated. As always thanks for your product and your responses.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 20-Sep-2006 10:34:42   

WayneBrantley wrote:

The methods DO work btw but in THIS particular scenario there's an ORDER in which things have to happen, and that's unfortunately, not suiting YOUR situation

I did not mean to imply YOUR methods do not work cry - Given the 'order problem' there would be certain ways to construct the object that would cause my code not to work (because the sort order is wrong) and other ways where it would work fine. That seems very bad, so would seem better to just place the sorting code everywhere throughout the project.

I might be the only one (wouldn't be the first time) one who wants to preset the order the collections are sorted in with my custom class! Does everyone else sets them everytime the use the object throughout all systems?

In fact, I have often thought of a 'feature request' - being able to choose which fields are sorted and asc/desc in the designer - then it could be generated right into the object. I was even considering doing an add-on using custom properties to make this happen, but it seems I cannot without modifying the shipping templates...

Is this feature on your feature request list?

I'll add a feature which adds a new virtual method called OnInitMembersCompleted() or something, which is called at the end of initmembers, so you can override that method and do whatever you want with the members. simple_smile

... which you can fill with an include template

I could not find such a template place?

The template isn't there, you can bind a custom template to a custom templateid, Custom_EntityInitializationTemplate, however that code is added right above the OnInitialized() method call so it won't help much I'm afraid.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 1268
Joined: 10-Mar-2006
# Posted on: 21-Sep-2006 07:08:36   

I'll add a feature which adds a new virtual method called OnInitMembersCompleted() or something, which is called at the end of initmembers, so you can override that method and do whatever you want with the members.

You are fantastic - thanks! smile