UnitOfWork and refetch

Posts   
 
    
JimFoye avatar
JimFoye
User
Posts: 656
Joined: 22-Jun-2004
# Posted on: 13-Mar-2005 22:42:55   

I need to refetch my entity after saving it. I'm sticking it and a bunch of related records in a UnitOfWork2 class and passing that to my BLL which saves using an adapter. Uh....how do I refetch. I need to get the generated primary key, etc.

I thought this UnitOfWork2 class was just what I needed, but then I encountered the concurrency thing again and now this...so now I'm not sure it's what I want to do anymore. disappointed

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 14-Mar-2005 11:54:31   

You don't need to refetch to get the identity value back. Though you can use an overload of Add() to specify if you want to refetch or not.

Frans Bouma | Lead developer LLBLGen Pro
JimFoye avatar
JimFoye
User
Posts: 656
Joined: 22-Jun-2004
# Posted on: 14-Mar-2005 22:46:24   

Yep! Sloppiness on my part, I just wasn't holding on to my entity. Everything looks good.

JimFoye avatar
JimFoye
User
Posts: 656
Joined: 22-Jun-2004
# Posted on: 14-Mar-2005 22:52:50   

Ah, but there is a little catch! When I initially fetch this entity, I define some prefetch paths. So even though the uow object is refetching the entity, at that point it doesn't know anything about these prefetch paths! So I guess I must pass this entity back to my manager and ask it to "properly" refetch it!

Is it possible to attach the prefetch paths to the entity? Then it would be not be necessary to specify these when it is refetched? confused

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 15-Mar-2005 09:28:33   

JimFoye wrote:

Ah, but there is a little catch! When I initially fetch this entity, I define some prefetch paths. So even though the uow object is refetching the entity, at that point it doesn't know anything about these prefetch paths! So I guess I must pass this entity back to my manager and ask it to "properly" refetch it!

Is it possible to attach the prefetch paths to the entity? Then it would be not be necessary to specify these when it is refetched? confused

No simple_smile . The refetch flag is there to make the code refetch every saved entity, because these become out-of-sync after a save. This is done in the complete graph which is saved. So you don't have to refetch the path, that's been taken care of for you: every entity saved is refetched, every entity not saved is well.. not refetched simple_smile

Frans Bouma | Lead developer LLBLGen Pro
JimFoye avatar
JimFoye
User
Posts: 656
Joined: 22-Jun-2004
# Posted on: 15-Mar-2005 15:12:17   

But the properties mapped to related entities are null after the refetch!

POEntity.CreatedBy is mapped to a Person entity. Here's the code that fetches initially:


        public POEntity GetPO(int PONumber)
        {
            POEntity po = new POEntity(PONumber);
            // set prefetch paths
            IPrefetchPath2 prefetchPath = new PrefetchPath2((int)EntityType.POEntity);
            prefetchPath.Add(POEntity.PrefetchPathCreatedBy);
            prefetchPath.Add(POEntity.PrefetchPathPODetail);
            prefetchPath.Add(POEntity.PrefetchPathVendor);
            prefetchPath.Add(POEntity.PrefetchPathPOApprovals).SubPath.Add(POApprovalEntity.PrefetchPathPerson);
            adapter.FetchEntity(po, prefetchPath);
            return po;
        }

In my GUI I want to save changes to this object:


            uow.AddForSave(po, true);

followed by


            try
            {
                mgr.Save(uow);
            }
            catch (Exception ex)
            {
                ShowMessage("Error saving: " + ex.Message);
                return false;
            }
            POEntity po = (POEntity)Session["PO"];
            mgr.RefetchPO(po);
            FillForm();
            return true;

Notice my call to another manager function, RefetchPO(). I have to do that because POEntity.CreatedBy is null after I save it. At least, I think that's what's happening. If you don't think that could be the case I will recheck everything...

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 15-Mar-2005 15:26:44   

I don't know what happens in the RefetchPO method, but the refetch done by the DataAccessAdapter object is just an entity field refetch, i.e.: it re-reads the row from the db, fills the Fields object and that's it. So all related entities should still be there after that.

Frans Bouma | Lead developer LLBLGen Pro
JimFoye avatar
JimFoye
User
Posts: 656
Joined: 22-Jun-2004
# Posted on: 15-Mar-2005 21:29:07   

Never mind, my goof! frowning

[Edit]

Let me clarify a bit. When I fetch an existing PO, I use those prefetch paths you saw in my code before.

When I create a new PO, of course the CreatedBy property is null. But once I've inserted it, I need this property set. Just refecthing the entity doesn't do that, I have to refetch it with those prefecth paths. Thus, I don't think LLBLGenPro is doing anything wrong, but it did take me a bit to figure out that I've got to manage this myself.

I don't know if attaching a set of prefetch paths to an entity would be a good idea or not, though it seems it would smooth out the difference between new and existing entities, I could attach these paths anytime I make one (uh - switch to a factory I guess and not new() it like you see in my code), then stick it in the UnitOfWork object and not worry about it anymore. Then again, I suppose that would cause fetching of related entities when an existing entity is updated, which might be pointless (but then again, would it? perhaps those entities have changed and _should _be refetched))

I don't know................................................ confused

JimFoye avatar
JimFoye
User
Posts: 656
Joined: 22-Jun-2004
# Posted on: 18-Mar-2005 00:39:31   

Frans, I guess I'm ok with things as they are, but I wanted to make sure you caught the edit I made to my last message. sunglasses

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 18-Mar-2005 10:00:46   

Heh simple_smile

Ok I see your point. The 'refetch' flag you can specify for saves is for individual entity refetches, to make sure their in-memory representations is synced with the database versions.

If you want to fetch a graph of entities with the entity you already have in memory, it's best to set the refetch flag to false when saving and refetch the entity using the normal route, with a prefetch path.

I know it can be easier to have a prefetch path in the save, but I want to keep things separated, i.e.: keep things which are functionally different, in different methods.

Frans Bouma | Lead developer LLBLGen Pro
JimFoye avatar
JimFoye
User
Posts: 656
Joined: 22-Jun-2004
# Posted on: 18-Mar-2005 18:53:30   

Ok, I guess I'll look into this new functionality of pulling an entity out of the uow object. If my manager class can do that then it can do the graph refetch, my GUI shouldn't have to worry about a newly inserted PO being only partially there.