所以我刚刚在我正在开发的框架中修复了一个错误。伪伪代码如下所示:
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也会更改引用的缓存对象,因此它永远不会保存回数据库。我通过克隆缓存版本的对象来修复它,切断引用并允许我将新对象与缓存的对象进行比较。
我的问题是:有没有更好的方法可以做到这一点,有些模式,你可以推荐吗?我不可能是以前唯一做过此事的人:)
答案 0 :(得分:23)
我认为,脏跟踪是处理此问题的常用方法。类似的东西:
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();
答案 1 :(得分:1)
我做过类似的事情,但我也克隆了它。区别在于我有缓存进行克隆。将对象放入缓存时,缓存将首先克隆对象并存储克隆的版本(这样您就可以改变原始对象而不会中断缓存)。当您从缓存中获取对象时,缓存将返回对象的克隆而不是存储的对象(同样,调用者可以在不影响缓存/规范对象的情况下改变对象)。
我认为只要您存储/复制的数据很小,这是完全可以接受的。
答案 2 :(得分:1)
使用linq时,Marks anwser略有改进:
使用Linq时,从DB中获取实体会将每个对象标记为IsDirty。 我为此做了一个解决方法,当没有设置值时不设置IsDirty;对于此实例:null时。对于int,我将orig值设置为-1,然后检查它。但是,如果保存的值与未初始化的值相同(在我的示例中为null),则不起作用。
private string _name;
[Column]
public string Name
{
get { return _name; }
set
{
if (value != _name)
{
if (_name != null)
{
IsDirty = true;
}
_name = value;
}
}
}
通过以某种方式初始化后设置IsDirty,可能会进一步改进。