Asp.Net Cache, модифицирует объект из кеша и изменяет кешированное значение

У меня возникла проблема при использовании функциональности Asp.Net Cache. Я добавляю объект в кэш, а затем в другое время я получаю этот объект из кэша, изменяю одно из его свойств и сохраняю изменения в базе данных.

Но в следующий раз, когда я получаю объект из Cache, он содержит измененные значения. Поэтому, когда я изменяю объект, он модифицирует версию, содержащуюся в кеше, даже если я не обновил ее в кэше. Кто-нибудь знает, как я могу получить объект из кэша, который не ссылается на кешированную версию?

то есть.

Шаг 1:

Item item = new Item();
item.Title = "Test";
Cache.Insert("Test", item, null, DateTime.Now.AddHours(1), System.Web.Caching.Cache.NoSlidingExpiration);

Шаг 2:

Item item = (Item)Cache.Get("test");
item.Title = "Test 1";

Шаг 3:

Item item = (Item)Cache.Get("test");
if(item.Title == "Test 1"){
    Response.Write("Object has been changed in the Cache.");
}

Я понимаю, что в приведенном выше примере было бы разумно, что любые изменения в элементе будут отображаться в кеше, но моя ситуация немного сложнее, и я определенно не хочу, чтобы это произошло.

Ответы

Ответ 1

Кэш делает именно это, он кэширует все, что вы вложили в него.

Если кешировать ссылочный тип, получить ссылку и изменить ее, конечно, в следующий раз, когда вы загрузите кешированный элемент, он будет отражать изменения.

Если вы хотите иметь неизменяемый кешированный элемент, используйте struct.

Cache.Insert("class", new MyClass() { Title = "original" }, null, 
    DateTime.Now.AddHours(1), System.Web.Caching.Cache.NoSlidingExpiration);
MyClass cachedClass = (MyClass)Cache.Get("class");
cachedClass.Title = "new";

MyClass cachedClass2 = (MyClass)Cache.Get("class");
Debug.Assert(cachedClass2.Title == "new");

Cache.Insert("struct", new MyStruct { Title = "original" }, null, 
    DateTime.Now.AddHours(1), System.Web.Caching.Cache.NoSlidingExpiration);

MyStruct cachedStruct = (MyStruct)Cache.Get("struct");
cachedStruct.Title = "new";

MyStruct cachedStruct2 = (MyStruct)Cache.Get("struct");
Debug.Assert(cachedStruct2.Title != "new");