Reloading subcollection

Posts   
 
    
jonas
User
Posts: 16
Joined: 04-Oct-2005
# Posted on: 14-Dec-2005 08:24:45   

Hi

I have an entity "WorkWeek" with a subcollection of "TimePlan". When the user has changed the properties of one TimePlan, and chooses to cancel without saving the WorkWeek, I would like to rollback everything.

My current solution just calls adapter.FetchEntity on the current WorkWeek, including the prefetchpath of the sub collection

IPrefetchPath2 prefetchPath = new PrefetchPath2((int)EntityType.WorkWeekEntity); prefetchPath.Add(WorkWeekEntity.PrefetchPathTimePlan);

Context c = new Context(); c.Add(entity);

// // Fetch data // adapter.FetchEntity(entity, prefetchPath);

However, when I check the subcollection TimePlan it contains 1 dirty entity.

the easiest way, I suppose, is to clear the TimePlan collection before loading it again, but I wonder if there is another solution to this? Is there a property I can set to assure that all sub collections are refreshed as well??

/Jonas

jonas
User
Posts: 16
Joined: 04-Oct-2005
# Posted on: 14-Dec-2005 09:04:31   

The other solution, clearing the subcollection, didn't work either. Before FetchEntity, the subcollection TimePlan contains 0 items. After FetchEntity, it contains 12 items, and 1 of them is Dirty!!! Very strange behaviour...

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 14-Dec-2005 09:30:04   

Could you please submit a complete code snippet of the entire case?

Also a code snippet for the second solution would be of much help.

And what runtime library version you are using?

Thanks

jonas
User
Posts: 16
Joined: 04-Oct-2005
# Posted on: 14-Dec-2005 10:23:22   

At first, I would like to say that the reason for me to use a context is the following thread http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=4604

I have tried to repeat that behaviour today, and it is obvious that I need the context to get the correct data.

In my new problem, I have tried to not use the context, and then It works. So, I need to use a context to reflect updates that other people have done. But...I can not use the context, since it reuses dirty when I want to reload.

The other solution only does one thing, it calls: entity.TimePlan.Clear() before fetching the entity. But when the entity is fetched, I get the same old dirty data again.

I use november 28th version. Is that what you need to know??

jonas
User
Posts: 16
Joined: 04-Oct-2005
# Posted on: 14-Dec-2005 10:42:00   

Instead of trying to describe what I do, I could try do describe the result I want:

I need a way to restore the data of an entity and all of its subcollections to its original values. As easy as that...

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 14-Dec-2005 10:58:07   

jonas wrote:

Instead of trying to describe what I do, I could try do describe the result I want:

I need a way to restore the data of an entity and all of its subcollections to its original values. As easy as that...

A Context will make you re-use existing instances again, so you can fetch data into existing entities for example. If you want to re-load everything, simply reload the data in a new instance, otherwise you'll keep the state of the current entity and related entities.

Graph versioning isn't build in and is very difficult to achieve, due to branches of the graph which have to be versioned within the version. You can achieve entity-field versioning though, by using entity.SaveFields(name), then allow the user to update the entity, then when the user cancels, call entity.RollbackFields(name) and you'll get the original field values back.

If you want to read other user's values as well, you have to read the data again from the DB, which thus generally comes down to refetching the data into new instances (or clearing everything first then reload everything, which is simply more work).

Frans Bouma | Lead developer LLBLGen Pro
jonas
User
Posts: 16
Joined: 04-Oct-2005
# Posted on: 14-Dec-2005 11:45:03   

Ok, but since I work with a grid and a llblgen colelction as datasource, I want to avoid to create a new instance.

The problem from last month (see linka earlier in this thread)was solved using the following code that you gave me:

Context c = new Context(); c.Add(entity); // // Fetch data // adapter.FetchEntity(entity, prefetchPath);

When I changed the code to the following:

adapter.FetchEntity(entity, prefetchPath, c);

My current problem was solved. But...of course the old problem with refetching data that some other user had changed reoccurred.

Is there not any way to reload all data of an existing entity instance with its subcollections. A reload method that both gets all changed data from the database and overwrites all other changes that I have made to the instance???

jonas
User
Posts: 16
Joined: 04-Oct-2005
# Posted on: 14-Dec-2005 11:58:15   

I do like this now, seems to work. I create a new entity based on the id of the old, load it and set the old instance to the new one.

However, this only works if the TimePlan collection is cleared. If not, the old dirty value seems to be contained in some context memory somewhere...

WorkWeekEntity newEntity = new WorkWeekEntity(entity.Id); // // Clear child collections // entity.TimePlan.Clear();

// // Reload data // LoadWorkWeek(newEntity); entity = newEntity;

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 14-Dec-2005 15:13:54   

When you want to rollback your changes and re-load your entity with its persisted related entities, why don't you remove it from the context and then re-add it again when you load it.

jonas
User
Posts: 16
Joined: 04-Oct-2005
# Posted on: 14-Dec-2005 22:31:50   

Well, I tried that and it seems to work now.

The code below, in combination however with clearing all subcollections with Clear() before creating a new context and re-fetching seems to work in all cases...

I get rid of added items, get back deleted, dirty ones are restored and items changed by someone else in the database are also reflected.

if (entity.ActiveContext != null) entity.ActiveContext = null;

Thanks