Refreshing entity

Posts   
 
    
Robert.W
User
Posts: 79
Joined: 19-Jun-2007
# Posted on: 02-Feb-2009 09:56:58   

Hi,

I need to refresh entity in-place but have trouble finding an API to do this. Let's say we have a method:

void ActOnMyEntity(MyEntity entity) { // Do Something and refetch entity so that entity has the latest data from the database }

when I exit this method I want the entity I supplied as a parameter have the latest value from the database. Tried to fetch the new version write its xml and then read it into entity reference but I guess it appends data and not replaces it?

Any ideas on how I could achieve that (without refetching on save)?

Best regards, Robert Wilczynski.

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 02-Feb-2009 10:50:21   

1- Adapter or SelfService? 2- Runtime library version?

Robert.W
User
Posts: 79
Joined: 19-Jun-2007
# Posted on: 02-Feb-2009 11:16:58   

1 - Adapter 2 - 2.6.8.606

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 02-Feb-2009 11:45:58   

Try the following:

void ActOnMyEntity(MyEntity entity)
{
// Do Something and refetch entity so that entity has the latest data from the database
DataAccessAdapter adapter = new DataAccessAdapter();
adapter.FetchEntity(entity);
}

By the way, you are using a very old build/version of the runtime library. Please download nad use the latest.

Robert.W
User
Posts: 79
Joined: 19-Jun-2007
# Posted on: 02-Feb-2009 17:19:53   

Will it refresh the entity including all prefetch patchs that I used to fetch the original entity, I need entities loaded by prefetch paths refreshed too?

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 03-Feb-2009 06:30:24   

If you want to refresh all graph, you have to pass the prefetchPath to the FetchEntity call.

David Elizondo | LLBLGen Support Team
Robert.W
User
Posts: 79
Joined: 19-Jun-2007
# Posted on: 06-Feb-2009 11:08:48   

Tried that bu it doens't seem to work - I'm getting similar errors as when I used writexml readxml approach to refresh entity content.

Please confirm that followin should give exactly the same result:

(1) MyEntity entity = GetEntity(1); //Some operations, saving entity with id 1 using another reference to it. entity = GetEntity(1); // entity is up to date !!!

MyEntity entity = GetEntity(1); //Some operations, saving entity with id 1 using another reference to it. entity.RefreshEntity(); // entity is up to date !!!

MyEntity GetEntity(int id) { MyEntity entity = new MyEntity(id); using (DataAccessAdapter adapter = new DataAccessAdapter()) { adapter.FetchEntity(entity, COMPLEX PREFETCH PATH HERE); } return entity; }

public static void RefreshEntity(this MyEntity entity) { using (DataAccessAdapter adapter = new DataAccessAdapter()) { adapter.FetchEntity(entity, COMPLEX PREFETCH PATH HERE); } }

BTW: I updated to 2.6.09.0116 (libraries only, not LLBLGen app)

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 06-Feb-2009 11:14:09   

What xml errors? Please post any exception text and stack trace that you are getting.

Maybe you don't need the Refresh method after all and insted of:

entity.RefreshEntity(); // entity is up to date !!!

You should jsut use:

entity = GetEntity(entity.Id); // entity is up to date !!!
Robert.W
User
Posts: 79
Joined: 19-Jun-2007
# Posted on: 06-Feb-2009 15:46:03   

Well, errors I get are assertions in unit tests. It seems that refetching into already fetched entity appends items to children collections like:

MyEntity.MyRelatedEntitiesCollection has 3 elements but after entity.RefreshEntity(); it has 6 even though none were added

Of course I don;t need to use entity.RefreshEntity(); but I want to - this will make the code more readable if I can have methods like

DoSomething(static MyEntity entity) { // Something done entity.Refresh(); }

and then use it like

entity.DoSomething();

then doing the following 100s times in my tests

entity.DoSomething(); entity = GetEntity(entity.Id);

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 07-Feb-2009 04:47:08   
public static void RefreshEntity(this MyEntity entity)
{

     // clear related entities
     entity.MyRelatedEntitiesCollection.Clear();

     // fetch
     using (DataAccessAdapter adapter = new DataAccessAdapter())
     {
          adapter.FetchEntity(entity, COMPLEX PREFETCH PATH HERE);
     }
}

You also could do

entity.MyRelatedEntitiesCollection.DoNotPerformAddIfPresent = true

However, that wont update the prefetched entities. So I think the best is clean the related collections before the fetch operation.

David Elizondo | LLBLGen Support Team
rdhatch
User
Posts: 198
Joined: 03-Nov-2007
# Posted on: 10-Feb-2009 10:02:50   

Hi Robert,

Just for clarification - Are you trying to Refetch the graph from the Database, assuming someone else has updated it? Or, might you be trying cancel/rollback some changes the user made to the entities? If the latter - you may want to create a deep copy of the graph in memory (I created a RestorePoint class for this) before the user is allowed to change things and then rolling back to the RestorePoint graph if they click cancel? Trying to take another view of what you might be needing solved.

Hope this helps!

Ryan

Robert.W
User
Posts: 79
Joined: 19-Jun-2007
# Posted on: 10-Feb-2009 11:01:46   

Ryan,

I do need to refetch from the database to get updates made to an entity since I loaded it. Thanks for the input though.

David,

Clearing related entity collections by hand will work but I was looking for a solution I won't have to keep an eye on when I modify my entity (I agree adding related entities is not that comon after the system matures but still).

Any other ideas? Maybe implementing RefetchEntity method on adapter in LLBLGen v next?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 10-Feb-2009 11:53:14   

though what exactly do you want: do you want to refresh the data in an entity object, or do you also update the collections / references ? Because that's a different thing.

Refreshing an individual entity or entities in a graph with a prefetch path can be done with the context: fetch the whole graph again while specifying a Context object will make sure the new data is updated in the existing entity objects.

However, this doesnt necessarily remove entity objects from the existing object graph if the entity instance (the data) is no longer available in the DB, as that's not its job: it simply fetches the entities again and instead of placing the data into new objects, it places the data into existing objects.

IMHO it's much easier to refetch the graph into new objects and get rid of the old one.

Frans Bouma | Lead developer LLBLGen Pro