Domanda

Quindi ho appena corretto un bug in un framework che sto sviluppando.Lo pseudo-pseudocodice si presenta così:

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

Quindi, in sostanza, stavo ottenendo un oggetto dalla cache e poi confrontavo l'oggetto originale con l'oggetto memorizzato nella cache per vedere se avevo bisogno di salvarlo nel database nel caso fosse cambiato.Il problema è sorto perché l'oggetto originale è un riferimento... quindi la modifica di someValue ha modificato anche l'oggetto memorizzato nella cache di riferimento, quindi non sarebbe mai stato salvato nel database.L'ho risolto clonando l'oggetto dalla versione memorizzata nella cache, interrompendo il riferimento e permettendomi di confrontare il nuovo oggetto con quello memorizzato nella cache.

La mia domanda è: c'è un modo migliore per farlo, qualche modello, che potresti consigliare? Non posso essere l'unica persona ad averlo già fatto :)

È stato utile?

Soluzione

Penso che il dirty tracking sia il modo normale per gestire questa situazione.Qualcosa di simile a:

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

Altri suggerimenti

Ho fatto cose simili, ma ho risolto il problema anche clonando.La differenza è che ho fatto eseguire la clonazione alla cache.Quando inserisci un oggetto nella cache, la cache clonerà prima l'oggetto e memorizzerà la versione clonata (in modo da poter modificare l'oggetto originale senza avvelenare la cache).Quando ottieni un oggetto dalla cache, la cache restituisce un clone dell'oggetto invece dell'oggetto memorizzato (di nuovo in modo che il chiamante possa modificare l'oggetto senza influenzare l'oggetto memorizzato nella cache/canonico).

Penso che questo sia perfettamente accettabile fintanto che i dati che stai archiviando/duplicando sono piccoli.

Un piccolo miglioramento sulla risposta di Marks quando si utilizza linq:

Quando si utilizza Linq, il recupero di entità dal DB contrassegnerà ogni oggetto come IsDirty.Ho trovato una soluzione alternativa a questo problema, non impostando IsDirty quando il valore non è impostato;per questa istanza:quando nullo.Per gli int, ho impostato il valore orig su -1 e poi ho controllato.Ciò non funzionerà, tuttavia, se il valore salvato è uguale al valore non inizializzato (null nel mio esempio).

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

Probabilmente potrebbe essere ulteriormente migliorato impostando IsDirty dopo l'inizializzazione in qualche modo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top