2008-08-28 86 views
11

所以我剛剛修復了我正在開發的框架中的一個錯誤。僞僞代碼如下所示:ASP.NET中的緩存模式

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也改變了引用的緩存對象,所以它永遠不會保存回數據庫。我通過克隆緩存版本的對象來修復它,切斷引用並允許我將新對象與緩存的對象進行比較。

我的問題是:有沒有更好的方法來做到這一點,一些模式,你可以推薦?我不能是唯一一個這樣做過的人:)

回答

20

我認爲,髒跟蹤是處理這個問題的常用方法。喜歡的東西:

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

有很多事情我不知道語言和語法。 +1,因爲我知道你可以在一個公共財產內部設置一個私密的私鑰。真棒隨之而來! – theo 2008-10-09 02:20:39

1

我已經做了類似的事情,但我通過克隆也解決了這個問題。不同的是我有緩存做克隆。當您將對象放入緩存時,緩存將首先克隆對象並存儲克隆版本(這樣您可以在不中毒緩存的情況下改變原始對象)。從緩存中獲取對象時,緩存將返回對象的克隆而不是存儲對象(再次,以便調用方可以在不影響緩存/規範對象的情況下對對象進行變異)。

我認爲這是完全可以接受的,只要您存儲/複製的數據很小。

1

關於商標anwser有點起色使用LINQ時:

當使用LINQ,取出由DB實體將迎來每一個對象作爲IsDirty。 我爲此做了一個解決方法,未設置值時不設置IsDirty;對於這個實例:當爲null時。對於整數,我將原始值設爲-1,然後檢查。但是,如果保存的值與未初始化的值相同(在我的示例中爲null),這將不起作用。

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

可能可以通過以某種方式設置IsDirty後進一步改進。