New Posts New Posts RSS Feed: Cache not reloading when list contains unsaved entities
  FAQ FAQ  Forum Search   Calendar   Register Register  Login Login

Cache not reloading when list contains unsaved entities

 Post Reply Post Reply
Author
chuckc View Drop Down
Groupie
Groupie


Joined: 27-Feb-2010
Posts: 54
Post Options Post Options   Quote chuckc Quote  Post ReplyReply Direct Link To This Post Topic: Cache not reloading when list contains unsaved entities
    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.

 

Back to Top
sbelini View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 13-Aug-2010
Location: Oakland
Posts: 786
Post Options Post Options   Quote sbelini Quote  Post ReplyReply Direct Link To This Post 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.
Back to Top
chuckc View Drop Down
Groupie
Groupie


Joined: 27-Feb-2010
Posts: 54
Post Options Post Options   Quote chuckc Quote  Post ReplyReply Direct Link To This Post 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.
Back to Top
sbelini View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 13-Aug-2010
Location: Oakland
Posts: 786
Post Options Post Options   Quote sbelini Quote  Post ReplyReply Direct Link To This Post 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.
Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down