Вопрос

Итак, я только что исправил ошибку в фреймворке, который я разрабатываю.Псевдо-псевдокод выглядит следующим образом:

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();

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

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

Это было полезно?

Решение

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

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();

Другие советы

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top