New Posts New Posts RSS Feed: Cache ignored when a view closed and then opened
  FAQ FAQ  Forum Search   Calendar   Register Register  Login Login

Cache ignored when a view closed and then opened

 Post Reply Post Reply
Author
alindzon View Drop Down
Newbie
Newbie
Avatar

Joined: 28-Jul-2010
Location: Toronto
Posts: 31
Post Options Post Options   Quote alindzon Quote  Post ReplyReply Direct Link To This Post Topic: Cache ignored when a view closed and then opened
    Posted: 19-Oct-2010 at 3:49am
I am trying to fully understand the cacheing.  If I completely load a file, all subsequent access seems to be through cache, which is great.  If I retrieve only a portion of the file, and page through it, again the cache works fine while the current UI is running.  But if I close and reopen the view, or open a second view onto the same data, the cache is not used.
 
I am curious what the default cacheing behaviours are, and if I can influence them to use cache when its available, even in those cirumstances.
 
This is one of the viewmodels involved

public class CustomersViewModel : ViewModelBase

{

public class MyDataContext

{

storeEntities _Context;

public storeEntities Context

{

get

{

if (_Context == null)

{

_Context = new storeEntities();

}

return _Context;

}

}

MyQueryableCollectionView _Data;

public MyQueryableCollectionView Data

{

get

{

if (_Data == null)

{

var collection = new RadObservableCollection<Customer>();

_Data = new MyQueryableCollectionView(collection);

_Data.PageSize = 10;

Refresh(true);

}

return _Data;

}

}

void Refresh(Boolean needsRefresh)

{

IdeaBlade.EntityModel.EntityScalarQueryOperation<int> countQuery;

if (needsRefresh)

{

countQuery = (from o in (EntityQuery<Customer>)Context.Customers.Where(_Data.FilterDescriptors) select o).AsScalarAsync().Count();

countQuery.Completed += (sender, args) =>

{

_Data.SetTotalItemsCount(args.Result);

};

}

var query = (EntityQuery<Customer>)Context.Customers.OrderBy(o => o.Company)

.Where(Data.FilterDescriptors)

.Sort(Data.SortDescriptors)

.Page(Data.PageIndex, Data.PageSize);

query.ExecuteAsync().Completed += (s, e) =>

{

var source = (RadObservableCollection<Customer>)_Data.SourceCollection;

source.SuspendNotifications();

source.Clear();

source.AddRange(e.Results);

source.ResumeNotifications();

_Data.CollectionChanged += CollectionChanged;

};

}

void CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)

{

_Data.CollectionChanged -= CollectionChanged;

Refresh((((Telerik.Windows.Data.QueryableCollectionView)(sender))).NeedsRefresh);

}

 

public class MyQueryableCollectionView : QueryableCollectionView

{

public MyQueryableCollectionView(IEnumerable source)

: base(source)

{ }

private int itemCount;

protected override IQueryable CreateView()

{

return IsGrouped ? QueryableSourceCollection.GroupBy(GroupDescriptors) : QueryableSourceCollection;

}

internal void SetTotalItemsCount(int count)

{

itemCount = count;

OnPropertyChanged(new PropertyChangedEventArgs("ItemCount"));

OnPropertyChanged(new PropertyChangedEventArgs("TotalItemCount"));

}

public override int TotalItemCount

{

get

{

return itemCount;

}

protected set

{

base.TotalItemCount = value;

}

}

public override int ItemCount

{

get

{

return itemCount;

}

}

}

}

}

}

 
Back to Top
sbelini View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 13-Aug-2010
Location: Oakland
Posts: 735
Post Options Post Options   Quote sbelini Quote  Post ReplyReply Direct Link To This Post Posted: 22-Oct-2010 at 11:50am
alindzon,
 
Each EntityManager has its own entity cache and query cache.
 
When you execute a query, the query is stored in the entity manager's query cache and the result set in the entity cache.
 
If you execute a query and it's already in the query cache, the entity will recognize that and only look in the entity cache, otherwise it will look in the datasource.
 
You can find detailed information on entity cache at http://drc.ideablade.com/xwiki/bin/view/Documentation/EntityCaching_Intro 
and about the query cache at
http://drc.ideablade.com/xwiki/bin/view/Documentation/AdvPersist_Intro#HQueryCache
 
When you reopen a view or open a second view, are they all working with the same instance of the entity manager?
Is the same query being re-executed, or are you executing a different query? 
Back to Top
alindzon View Drop Down
Newbie
Newbie
Avatar

Joined: 28-Jul-2010
Location: Toronto
Posts: 31
Post Options Post Options   Quote alindzon Quote  Post ReplyReply Direct Link To This Post Posted: 22-Oct-2010 at 12:01pm
Now this is getting interesting.  So if I want my application to retrieve data from the cache and to share the cache, I should create one instance of the entity manager when I start the application, and use it for each viewmodel, without creating new instances.
 
But if I want something to be completely independant, and to not be corrupted by the other viewmodels,  then I should create a new instance of the entity manager.  Does that make sense?
 
Back to Top
smi-mark View Drop Down
DevForce MVP
DevForce MVP
Avatar

Joined: 24-Feb-2009
Location: Dallas, Texas
Posts: 307
Post Options Post Options   Quote smi-mark Quote  Post ReplyReply Direct Link To This Post Posted: 22-Oct-2010 at 12:18pm
One way is to create a new EntityManager for each view, you then import the cache from the master EntityManager.
Back to Top
alindzon View Drop Down
Newbie
Newbie
Avatar

Joined: 28-Jul-2010
Location: Toronto
Posts: 31
Post Options Post Options   Quote alindzon Quote  Post ReplyReply Direct Link To This Post Posted: 22-Oct-2010 at 12:21pm
Please show me how you would make the master entitymanager available to the views, and how you would import the cache.
Back to Top
alindzon View Drop Down
Newbie
Newbie
Avatar

Joined: 28-Jul-2010
Location: Toronto
Posts: 31
Post Options Post Options   Quote alindzon Quote  Post ReplyReply Direct Link To This Post Posted: 23-Oct-2010 at 8:55am
It looks like there are two options, a master entitymanager, or using one entitymanager for the entire application.  I am assuming from a memory perspective one entitymanager is better since then you will not have all those duplicate caches running around.
 
Tell me if this makes sense, and please show me how you would set it up, and then connect to it from each repository.  I am still new to C# and this object stuff, my main experience was long ago with C+, so I am still getting used to hooking things up.
 
Back to Top
alindzon View Drop Down
Newbie
Newbie
Avatar

Joined: 28-Jul-2010
Location: Toronto
Posts: 31
Post Options Post Options   Quote alindzon Quote  Post ReplyReply Direct Link To This Post Posted: 24-Oct-2010 at 8:42am
Based on your documentation I am not sure if this will work or not since it is still a new query.
 
So let me put the questions another way.
 
if you want to load specific tables completely once when a program starts up, and then to use those tables for something like includes for many views without accessing the database again, how would you do it.
 
Examples are
Manufacturer Names, referenced by ManufacturerID
Distributor Names, referenced by DistributorID
State Names and Tax Rates referenced by StateID
etc...
 
Right now when the application starts, these viewmodels are all executed successfuly and if those views are used, there is no database access.  But if that data is required for another view then the cache is ignored.
 
From a design perspective, it makes no sense to go to the database for data that has already been loaded in its entirety into cache.  So what is the optimal devforce way to take advantage of this data, to reduce the need to retrieve this data over and over again from the database?
 
Also how would one write the query so that it retrieves only the desired fields from the database for the view in question?  I undertstand there is a way with a lamda expression.
 
 
Back to Top
WardBell View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 31-Mar-2009
Location: Emeryville, CA,
Posts: 338
Post Options Post Options   Quote WardBell Quote  Post ReplyReply Direct Link To This Post Posted: 24-Oct-2010 at 11:34pm
Alindzon
 
We cannot make sense of your claims. DevForce does not know about ViewModels. If you see one kind of behavior with one set of VMs and different behavior with a different set of VMs, it is most probable that the explanation is to be found in your VMs. I suspect that you are using multiple EntityManagers and have lost track of what they hold.
 
--
"how would one write the query so that it retrieves only the desired fields from the database for the view in question?"
You'll find examples of projection in the Cookbook here and here.
Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down