Fetch With Prefetch -> Save -> Refetch

Posts   
 
    
Devildog74
User
Posts: 719
Joined: 04-Feb-2004
# Posted on: 27-Apr-2006 08:28:30   

I have an entity that is fetched with a prefetch, using this construct: MyCustomEntity.Fetch() which returns an instance of MyCustomEntity filled with all data.

Then I put the entity in session.

Then I edit the entity stored in session and items in its member properties.

Then I call adapter.SaveEntity(entityToSave); entity to save is the entity that was in session. This marks the entity as out of synch and makes it unusable.

So now I have to refetch the entity. If I use this method, adapter.SaveEntity(entityToSave, true) the select statement that is run at the end of the save does not appear to be populating all entities specified in the original prefetch.

I thought that maybe I needed to add my entity to context before calling SaveEntity. This did not work as only a partial graph is returned and I am getting a null reference exception pointing to one of the member properties of my entity that was saved.

This is what my code looked like after adding the context:


using (DataAccessAdapter adapter = new DataAccessAdapter(ConnectionString))
{
    Context currentContext = new Context();
    currentContext.Add(entityToSave);

    adapter.SaveEntity(entityToSave , true);
}

So my question is, should the SaveEntity(entityToSave , true) do the select using the preexisting prefetch and return all of the objects again?

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 27-Apr-2006 08:38:07   

So my question is, should the SaveEntity(entityToSave , true) do the select using the preexisting prefetch and return all of the objects again?

No it should not, you'd better fetch it the same way you did the first time, using prefetchPaths.

Devildog74
User
Posts: 719
Joined: 04-Feb-2004
# Posted on: 27-Apr-2006 08:40:58   

In addition, this code ((CustomTrainingEntry)entity).ExerciseDetail.Count == 6. The next set of code works for all items in the ExerciseDetail collection EXCEPT for the record that I modified.

This code this code == null reference exception


((ExerciseDetailEntity)((CustomTrainingEntry)entity).ExerciseDetail[0]).Exercise.ExerciseName 

But, this codeworks fine, and actually, the code below works for items 1 through 5 of the ExerciseDetail collection.


((ExerciseDetailEntity)((CustomTrainingEntry)entity).ExerciseDetail[1]).Exercise.ExerciseName 

I am executing the statements in this post from the immediate window, after the save has returned. Ther are 0 DirtyEntities in the ExerciseDetail Collection.

Devildog74
User
Posts: 719
Joined: 04-Feb-2004
# Posted on: 27-Apr-2006 08:49:15   

Walaa wrote:

So my question is, should the SaveEntity(entityToSave , true) do the select using the preexisting prefetch and return all of the objects again?

No it should not, you'd better fetch it the same way you did the first time, using prefetchPaths.

Bummer. If an entity is fetched with a prefetch path, and the same entity is used later in a save operation, why is the prefetch that was used disregarded? I also thought that using context was supposed to help overcome these types of issues.

It seems to me that when you call fetch entity on the adapter, and pass in the entity to fetch and the prefetch path that you could tuck away the prefetch path into the entity that is being filled so that they runtime could use the prefetch path later.

It just seems like sometimes there is inconsitent behavior.

Thanks for the quick reply though.

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 27-Apr-2006 08:51:34   

Ther are 0 DirtyEntities in the ExerciseDetail Collection.

After or before the save?

Did you try to fetch the entire graph as I suggested earlier?

Devildog74
User
Posts: 719
Joined: 04-Feb-2004
# Posted on: 27-Apr-2006 08:58:44   

Walaa wrote:

Ther are 0 DirtyEntities in the ExerciseDetail Collection.

After or before the save?

Did you try to fetch the entire graph as I suggested earlier?

There are 0 DirtyEntities after the save.

Yes I did try it, and your suggestion works fine, like so....


entity.Save();
// force refetch and session update
entity = SelectTrainingEntry(entity.TrainingEntryId, true);  

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 27-Apr-2006 09:12:58   

Do you still get the "null reference exception" after the "force refetch and session update"?

Devildog74
User
Posts: 719
Joined: 04-Feb-2004
# Posted on: 27-Apr-2006 09:24:52   

No, the null reference goes away. I accept the fact that the entity is not refetched using the prefetch path when setting the refetch argument == true in the SaveEntity method.

I think you are missing my point though. My point is this, by setting refetch == true, one would assume that the entity would be "refetched" the same way that it was "originally" fetched, because the entity and the prefetch path were both sent to the adapter the first time the fetch was performed.

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 27-Apr-2006 10:10:54   

I've got your point but that's not how it is currently designed.

Please check Frans last post on the following thread: http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=3635

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39928
Joined: 17-Aug-2003
# Posted on: 27-Apr-2006 10:20:00   

Refetch == true makes the save routine to refetch all SAVED entities again. So every entity that's not SAVED is not refetched because it's untouched. A refetch means: it selects the fields again and fills the fields object again, nothing further.

Frans Bouma | Lead developer LLBLGen Pro
Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 27-Apr-2006 14:45:49   

It seems that I was under the wrong impression. That related entities are not refetched I'm very sorry. flushed

So I'll repeat the correct piece of information: If you have a graph like 1 customer, 2 orders, and 2 order detail entities, and they're all dirty and get saved, they all get refetched when you specify refetch = true.