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