Print Page | Close Window

Editing a collection where the items need to load data depending of the context

Printed From: IdeaBlade
Category: Cocktail
Forum Name: Community Forum
Forum Discription: A professional application framework using Caliburn.Micro and DevForce
URL: http://www.ideablade.com/forum/forum_posts.asp?TID=3857
Printed Date: 11-Jul-2020 at 2:48pm


Topic: Editing a collection where the items need to load data depending of the context
Posted By: Walid
Subject: Editing a collection where the items need to load data depending of the context
Date Posted: 18-Dec-2012 at 9:06am
Hi, 

I wonder what is the best practice with Cocktail when a VM that allows to edit a list (such as address) of items that need to load data depending of the context

Currently, when an Item allow to set a navigation property via a Combobox I use the same collection (located in my ListVM) for all the items. But sometimes I need specific data for each of them.

In this case I see 2 possibilities:
1. Give to ItemVM the guid and it will handle the data loading.
=> Problem, part of the reference data is then in the ListVM, the other in the ItemVM.
      + I dont think there should be any loading (using the uow) in an ItemVM.
2. Create a specific collection in the ItemVM but let the ListVM handle the loading (in the propertyChanged event of the entity for example). Then assigned result to the ItemVM's collection.

I thinks the best solution might be the 2nd one but is this a good way to handle such scenario following the pattern in  Cocktail/Temphire ?




Replies:
Posted By: mgood
Date Posted: 18-Dec-2012 at 10:52am
There's nothing wrong with the first option. As long as both VMs share the same uow, the data is in the same place. If you go with option 2 you don't have loose coupling anymore. Your ListVM now needs to understand the logic in the ItemVM and feed it with additional data. It makes more sense to have the ItemVM do all that and be self-contained, so if you reuse the ItemVM in another compositon scenario you don't have to reimplement the loading of the contextual data.


Posted By: Walid
Date Posted: 18-Dec-2012 at 1:43pm
Ok.

So it's not a problem if the shared collection are now in the Item VM ? It sound more logical but I was afraid to get poor performances if every item had to create his own collection.


Posted By: mgood
Date Posted: 18-Dec-2012 at 1:55pm
No, it's not. The collection is just a list of pointers. If you have multiple VMs that fetch the same data from a repository, the query cache will make sure it's only fetched once from the datasource and subsequent fetches are satisfied from the cache. 

If you look at TempHire for example all the VMs composed into the DetailVM fetch the StaffingResource. The first fetch will bring it into the cache and the remaining VMs will transparently get it from the cache, so there's no performance hit. Just make sure you don't have more than one VM try fetching the same thing before it is in the cache, otherwise they will all go to the DB. 

You can see this handled in StaffingResourceDetailViewModel.LoadDataAsync. It waits for the staffing resource to be fetched into the cache before calling Start on all the nested VMs.

        private async void LoadDataAsync(Guid staffingResourceId, EditMode editMode)
        {
            using (Busy.GetTicket())
            {
                _unitOfWork = null;
                _staffingResourceId = staffingResourceId;
                EditMode = editMode;

                StaffingResource = await UnitOfWork.StaffingResources.WithIdAsync(staffingResourceId);
                StaffingResourceSummary.Start(StaffingResource.Id, EditMode);
                _sections.ForEach(s => s.Start(StaffingResource.Id, EditMode));
                if (Items.Count == 0)
                {
                    Items.AddRange(_sections.OrderBy(s => s.Index));
                    NotifyOfPropertyChange(() => Items);
                    ActivateItem(Items.First());
                }
            }
        }


Posted By: mgood
Date Posted: 18-Dec-2012 at 1:58pm
A little caveat I forgot to mention. If the fetch involves a projection then the situation is a little different, because projection queries are not cached. In that case you need to manually make sure that your LineItemVMs retrieve the data from the cache and somewhere higher up make sure the necessary data is loaded into the cache. 


Posted By: Walid
Date Posted: 18-Dec-2012 at 2:02pm
I am confused, I though the projection weren't in the EntityManager cache


Posted By: Walid
Date Posted: 18-Dec-2012 at 2:04pm
nevermind I misread your post

Thanks Marcel



Print Page | Close Window