Question

Je viens donc de corriger un bug dans un framework que je développe.Le pseudo-pseudocode ressemble à ceci :

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

Donc, essentiellement, j'obtenais un objet du cache, puis je comparais plus tard l'objet d'origine à l'objet mis en cache pour voir si je devais l'enregistrer dans la base de données au cas où il serait modifié.Le problème est survenu parce que l'objet d'origine est une référence... donc changer someValue a également modifié l'objet mis en cache référencé, de sorte qu'il ne sera jamais sauvegardé dans la base de données.Je l'ai corrigé en clonant l'objet de la version en cache, en coupant la référence et en me permettant de comparer le nouvel objet avec celui en cache.

Ma question est: existe-t-il une meilleure façon de procéder, un modèle, que vous pourriez recommander ? Je ne peux pas être la seule personne à avoir déjà fait ça :)

Était-ce utile?

La solution

Un suivi sale est la manière normale de gérer cela, je pense.Quelque chose comme:

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

Autres conseils

J'ai fait des choses similaires, mais j'ai aussi contourné ce problème en clonant.La différence est que j'ai demandé au cache de faire le clonage.Lorsque vous placez un objet dans le cache, le cache clone d'abord l'objet et stocke la version clonée (vous pouvez ainsi muter l'objet d'origine sans empoisonner le cache).Lorsque vous récupérez un objet du cache, le cache renvoie un clone de l'objet au lieu de l'objet stocké (encore une fois afin que l'appelant puisse muter l'objet sans affecter l'objet mis en cache/canonique).

Je pense que cela est parfaitement acceptable tant que les données que vous stockez/dupez sont petites.

Une petite amélioration de la réponse de Marks lors de l'utilisation de Linq :

Lors de l'utilisation de Linq, la récupération des entités de la base de données marquera chaque objet comme IsDirty.J'ai trouvé une solution de contournement pour cela, en ne définissant pas IsDirty lorsque la valeur n'est pas définie ;pour cet exemple :quand nul.Pour les entiers, j'ai placé la valeur d'origine à -1, puis j'ai vérifié cela.Cela ne fonctionnera cependant pas si la valeur enregistrée est la même que la valeur non initialisée (nulle dans mon exemple).

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

Pourrait probablement être amélioré davantage en définissant IsDirty après l'initialisation d'une manière ou d'une autre.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top