15

そこで、開発中のフレームワークのバグを修正しました。擬似擬似コードは次のようになります。

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 を変更すると、参照されているキャッシュされたオブジェクトも変更され、データベースに保存されなくなります。キャッシュされたバージョンからオブジェクトを複製し、参照を切断して、新しいオブジェクトをキャッシュされたオブジェクトと比較できるようにすることで、これを修正しました。

私の質問は、これを行うためのより良い方法、推奨できるパターンはありますか? 以前にこれを行ったのは私だけではありません:)

4

3 に答える 3

25

ダーティトラッキングはこれを処理する通常の方法だと思います。何かのようなもの:

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();
于 2008-08-29T01:51:02.760 に答える
1

linq を使用する場合の Marks anwser の少しの改善:

Linq を使用する場合、DB からエンティティをフェッチすると、すべてのオブジェクトが IsDirty としてマークされます。値が設定されていない場合は IsDirty を設定しないことで、これを回避しました。このインスタンスの場合: null の場合。int の場合、orig-value を -1 に設定してから、それを確認しました。ただし、保存された値が初期化されていない値 (私の例では null) と同じ場合、これは機能しません。

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

何らかの方法で初期化後に IsDirty を設定することで、おそらくさらに改善される可能性があります。

于 2012-02-23T14:50:29.303 に答える
1

私も似たようなことをしましたが、クローンも作成して回避しました。違いは、キャッシュにクローンを作成させたことです。オブジェクトをキャッシュに入れると、キャッシュは最初にオブジェクトを複製し、複製されたバージョンを保存します (キャッシュをポイズニングせずに元のオブジェクトを変更できます)。キャッシュからオブジェクトを取得すると、キャッシュは格納されたオブジェクトの代わりにオブジェクトのクローンを返します (これにより、呼び出し元はキャッシュされた/正規のオブジェクトに影響を与えずにオブジェクトを変更できます)。

保存/複製しているデータが小さい限り、これは完全に許容できると思います。

于 2008-08-28T22:02:53.150 に答える