Frage

Deshalb habe ich gerade einen Fehler in einem Framework behoben, das ich entwickle.Der Pseudo-Pseudocode sieht so aus:

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

Im Wesentlichen holte ich also ein Objekt aus dem Cache und verglich später das Originalobjekt mit dem zwischengespeicherten Objekt, um zu sehen, ob ich es für den Fall einer Änderung in der Datenbank speichern muss.Das Problem entstand, weil das ursprüngliche Objekt eine Referenz ist. Durch die Änderung von someValue wurde also auch das referenzierte zwischengespeicherte Objekt geändert, sodass es nie wieder in der Datenbank gespeichert werden konnte.Ich habe das Problem behoben, indem ich das Objekt aus der zwischengespeicherten Version geklont habe, die Referenz getrennt habe und es mir ermöglicht habe, das neue Objekt mit dem zwischengespeicherten zu vergleichen.

Meine Frage ist: Gibt es einen besseren Weg, ein Muster, das Sie empfehlen könnten? Ich kann nicht der Einzige sein, der das schon einmal gemacht hat :)

War es hilfreich?

Lösung

Ich denke, Dirty Tracking ist der normale Weg, damit umzugehen.Etwas wie:

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

Andere Tipps

Ich habe ähnliche Dinge getan, aber ich habe es auch durch Klonen umgangen.Der Unterschied besteht darin, dass ich das Klonen vom Cache durchführen ließ.Wenn Sie ein Objekt in den Cache legen, klont der Cache zuerst das Objekt und speichert die geklonte Version (so dass Sie das ursprüngliche Objekt mutieren können, ohne den Cache zu vergiften).Wenn Sie ein Objekt aus dem Cache abrufen, gibt der Cache einen Klon des Objekts anstelle des gespeicherten Objekts zurück (wiederum, damit der Aufrufer das Objekt ändern kann, ohne dass sich dies auf das zwischengespeicherte/kanonische Objekt auswirkt).

Ich denke, dass dies völlig akzeptabel ist, solange die Daten, die Sie speichern/duplizieren, klein sind.

Eine kleine Verbesserung der Marks-Antwort bei Verwendung von Linq:

Wenn Sie Linq verwenden, wird beim Abrufen von Entitäten aus der Datenbank jedes Objekt als IsDirty markiert.Ich habe eine Problemumgehung dafür vorgenommen, indem ich IsDirty nicht festgelegt habe, wenn der Wert nicht festgelegt ist.für diesen Fall:wenn null.Für Ints habe ich den Originalwert auf -1 gesetzt und dann überprüft.Dies funktioniert jedoch nicht, wenn der gespeicherte Wert mit dem nicht initialisierten Wert übereinstimmt (in meinem Beispiel null).

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

Könnte wahrscheinlich weiter verbessert werden, indem IsDirty irgendwie nach der Initialisierung festgelegt wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top