2008-08-28 3 views
11

Так что я просто исправил ошибку в рамках, которые я разрабатываю. Псевдо-псевдокод выглядит следующим образом:Кэширование шаблонов в ASP.NET

myoldObject = new MyObject { someValue = "old value" }; 
cache.Insert("myObjectKey", myoldObject); 
myNewObject = cache.Get("myObjectKey"); 
myNewObject.someValue = "new value"; 
if(myObject.someValue != cache.Get("myObjectKey").someValue) 
    myObject.SaveToDatabase(); 

Так, по существу, я получаю объект из кэша, а затем сравнивая исходный объект в кэше объекта, чтобы увидеть, если мне нужно, чтобы сохранить его в в случае его изменения. Проблема возникла из-за того, что исходный объект является ссылкой ... поэтому изменение someValue также изменило ссылочный кешированный объект, поэтому он никогда не будет возвращаться в базу данных. Я исправил его, клонировав объект с кешированной версии, отделив ссылку и позволив мне сравнить новый объект с кешированным.

Мой вопрос: Есть ли лучший способ сделать это, какой-то образец, который вы могли бы порекомендовать? Я не могу быть единственным человеком, который сделал это раньше :)

ответ

20

Грязное слежение - это нормальный способ справиться с этим, я думаю. Что-то вроде:

class MyObject { 
    public string SomeValue { 
    get { return _someValue; } 
    set { 
     if (value != SomeValue) { 
      IsDirty = true; 
      _someValue = value; 
     } 
    } 

    public bool IsDirty { 
    get; 
    private set; 
    } 

    void SaveToDatabase() { 
    base.SaveToDatabase(); 
    IsDirty = false; 
    } 
} 

myoldObject = new MyObject { someValue = "old value" }; 
cache.Insert("myObjectKey", myoldObject); 
myNewObject = cache.Get("myObjectKey"); 
myNewObject.someValue = "new value"; 
if(myNewObject.IsDirty) 
    myNewObject.SaveToDatabase(); 
+0

Есть много вещей, которые я не знаю о языках и синтаксисе. +1, потому что я узнал, что вы можете сделать сеттер частным в публичной собственности. Появляется удивительность! – theo 2008-10-09 02:20:39

1

Я делал схожие вещи, но я обошел его, клонируя тоже. Разница в том, что я сделал кеш клонирования. Когда вы кладете объект в кеш, кеш будет клонировать объект первым и хранить клонированную версию (чтобы вы могли мутировать исходный объект, не отравляя кеш). Когда вы получаете объект из кеша, кеш возвращает клонированный объект вместо сохраненного объекта (опять же, чтобы вызывающий объект мог мутировать объект без эффекта кэшированного/канонического объекта).

Я думаю, что это вполне приемлемо, если данные, которые вы храните/обманываете, невелики.

1

небольшое улучшение по Marks anwser при использовании LINQ:

При использовании Linq, извлечение объектов из БД будет отмечать каждый объект как IsDirty. Я сделал обходное решение для этого, не устанавливая IsDirty, когда значение не установлено; для этого экземпляра: когда null. Для ints я присваивал значение orig-значение -1, а затем проверял его. Однако это не сработает, если сохраненное значение совпадает с неинициализированным значением (null в моем примере).

private string _name; 
[Column] 
public string Name 
{ 
    get { return _name; } 
    set 
    { 
     if (value != _name) 
     { 
      if (_name != null) 
      { 
       IsDirty = true; 
      } 
      _name = value; 
     } 
    } 
} 

Возможно, возможно, было улучшено, установив IsDirty после инициализации каким-то образом.

Смежные вопросы