3

I have a View Model that I create and then return to my view. This view model is not cached. However, the view model contains a list of type "category" that is cached.

I do the usual "If in cache retrieve and return. If not in cache then retrieve data, store in cache and return" the view model to the controller. This works as expected.

My problem is just before I return my view model from my controller to my view I want to update a record in my list of categories but only for the page that called it (not for all users / pages that call it). When I do this it automatically updates the categories list in cache and I don’t want it to. I only insert the cache once so don’t understand why when I update the list once I have retrieved it from cache the change is reflected instantly in the cache.

This is probably me misunderstanding how OO / Cache works but am hoping someone can set me straight please?

The code in my controller...

var vm = new FsmViewModel();
if(vm.ActiveCategoryId > 0)
vm.Categories.Find(c => c.Category_ID == vm.ActiveCategoryId).ActiveBootstrapCss = "active";

The above code also updates the list of categories I have stored in cache? I am using the Proxy pattern to populate the categories list from cache or from database.

ObjectCache cache = MemoryCache.Default;
_categories = (List<Category>)cache[CacheForCategories];

if (_categories != null) return _categories;

// Cache does not exist so create
var policy = new CacheItemPolicy {AbsoluteExpiration = DateTimeOffset.Now.AddHours(4)};

_categories = base.GetAllCategories();
cache.Add(CacheForCategories, _categories, policy);

return _categories;

_categories is returned to my view model pulled from cache or db and is defined in my view model object as

public List<Category> Categories { get; set; }

Can someone please let me know what I am doing wrong here?

Thanks,

Paul

tereško
  • 58,060
  • 25
  • 98
  • 150
Paul Hale
  • 307
  • 4
  • 14

1 Answers1

5

You are not doing anything wrong. That is how the cache works out of box. It holds a reference to a object and not a copy of it. So if you load a object from the cache then it is basically the same object because you will receive just a reference to it.

You can make a deep copy of your object before you save it in the cache to avoid this behavior.

Community
  • 1
  • 1
Marian Ban
  • 8,158
  • 1
  • 32
  • 45
  • "deep copy" this is new to me. So I'm guessing if I newed up a new object something like... Categories = new List(cachedDbRepository.GetAllCategories()); this would not work as it would still reference the original object? Will experiment when back at my desk and post my findings. – Paul Hale Oct 06 '14 at 22:19
  • After a little thought this now makes perfect sense. Thankyou for setting me straight. – Paul Hale Oct 06 '14 at 22:55