Print Page | Close Window

Cache not reloading when list contains unsaved entities

Printed From: IdeaBlade
Category: DevForce
Forum Name: DevForce 2010
Forum Discription: For .NET 4.0
URL: http://www.ideablade.com/forum/forum_posts.asp?TID=3728
Printed Date: 13-Apr-2026 at 2:34am


Topic: Cache not reloading when list contains unsaved entities
Posted By: chuckc
Subject: Cache not reloading when list contains unsaved entities
Date Posted: 18-Oct-2012 at 7:46pm
I am seeing some undesired behavior when attempting to clear a navigation list property from the cache and re-query.  

Example:

// User 1 queries for contact Kelli Smith and looks up her work phone number.

Contact contact = _manager.Contacts.Where(c => c.Person.LastName == "Smith" && c.Person.FirstName == "Kelli").Single();

Phone workPhone = contact.Phones.Where(p => p.PhoneType.Name ==PhoneType.StandardPhoneNames.Work).FirstOrDefault();

Phone newPhone = null;
if (null == workPhone)
{

    // Kelli Smith has no work phone, so create one, but do not yet save.
    newPhone = Phone.Create(PhoneType.StandardPhoneNames.Work, _manager);
    newPhone.Number = "000";
    contact.Phones.Add(newPhone);
}

 // Meanwhile, User 2 saves a work phone number for Kelli Smith.

 // User 1 wants to refresh phone numbers for Kelli, so force cache to reload.

var f = contact.EntityAspect.GetNavigationProperty("Phones");

f.GetEntityReference(contact).IsLoaded = false;
f.GetEntityReference(contact).Load(MergeStrategy.OverwriteChanges);
workPhone = contact.Phones.Where(p => p.PhoneType.Name == PhoneType.StandardPhoneNames.Work).FirstOrDefault();

// Despite attempting to clear the cache and reload, workPhone at this point is still the
// phone number created (but not saved) above.

// Discard the created but unsaved phone number...
newPhone.EntityAspect.RejectChanges();

// ...and our navigation property now returns the phone number created and saved by User 2, as desired.
workPhone = contact.Phones.Where(p => p.PhoneType.Name == PhoneType.StandardPhoneNames.Work).FirstOrDefault();

 Is this the designed behavior?  It so, how can I refresh a navigation property query without having to manually discard unsaved navigation list members?

Thanks.

 




Replies:
Posted By: sbelini
Date Posted: 19-Oct-2012 at 12:35pm
Chuckc,
 
This is the expected behavior.
 
If you query for all work phone #s rather than just the first, you will have the one created by user 2 as well:
 
workPhone = contact.Phones.Where(p => p.PhoneType.Name == PhoneType.StandardPhoneNames.Work).ToList();
 
you asked "It so, how can I refresh a navigation property query without having to manually discard unsaved navigation list members?"
 
You should not expect .First() to bring an specific record ever. i.e. why would the work phone# created by user2 take precedence over newPhone? - they are both supposedly valid numbers and although newPhone is not in the DataBase (yet) it has EntityAspec.Added.
 
If by refresh you mean retrieving the number that is in the DB rather than what you have in cache only, (i.e. not saved) than you should run the query against the datasource only:
 
workPhone = contact.Phones.With(QueryStrategy.DataSourceOnly).Where(p => p.PhoneType.Name == PhoneType.StandardPhoneNames.Work).FirstOrDefault();
 
Regards,
    sbelini.


Posted By: chuckc
Date Posted: 19-Oct-2012 at 1:32pm
Thanks for the quick response.

I did not expect First() to bring back any specific record - that code is merely a contrived example.  

What I had hoped for is some is some combination of 

var f = contact.EntityAspect.GetNavigationProperty("Phones");
f.GetEntityReference(contact).IsLoaded = false;

 and /or 

f.GetEntityReference(contact).Load(MergeStrategy.OverwriteChanges); // or some other MergeStrategy??

or some other technique, that would flush the created but unsaved Phone entity out of the local cache. 

I am looking for some general purpose refresh approach that can be widely used without having to manually track new but unsaved entities, or manually switch query strategies to DataSourceOnly.  I just want to clear the cache of unsaved entities for a particular navigation property.  Is that possible?

Thanks.


Posted By: sbelini
Date Posted: 19-Oct-2012 at 2:03pm
Thanks for clarifying.
 
Although unsaved, the entity (newPhone) you created has been added to the EntityManager (by associating it with Contact) and is 'relevant' data at this point.
Because of that, you will indeed have to manually remove it by calling Delete or RejectChanges.
 
Regards.



Print Page | Close Window