2011-05-11 98 views
0

我有一個函數Ge​​tAllProducts(),它從數據庫中提取所有產品並將其存儲在緩存中以備將來使用。這工作正常,但如果我然後調用函數,例如ProductSearchResults = GetAllProducts(),然後修改ProductSearchResults變量,這也會修改緩存,這是非常重要的,因爲緩存會影響整個網站,所以這絕不會發生。對象引用和緩存

我知道這是因爲ProductSearchResults和緩存現在都有相同的引用,但我該如何解決問題?有什麼我可以放在GetAllProducts(),以確保緩存始終使用自己的值?

Public Shared Function GetAllProducts() As ProductCollection 

     Dim Products As New ProductCollection() 

     If IsNothing(System.Web.HttpContext.Current.Cache("ProductData")) Then 

      '////// Database code to get products goes here ////// 

      System.Web.HttpContext.Current.Cache.Insert("ProductData", Products, Nothing, DateTime.Now.AddMinutes(5), TimeSpan.Zero) 
     End If 
     Products = System.Web.HttpContext.Current.Cache("ProductData") 

     Return Products 

    End Function 

Public Shared Function SearchProducts(ByVal SearchText As String) As ProductCollection 

     Dim ProductSearchResults As ProductCollection = Nothing 

     If SearchText <> "" Then 

      SearchText = SearchText.ToLower() 

      Dim Keywords As New ArrayList() 
      Keywords.AddRange(SearchText.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)) 

      ProductSearchResults = GetAllProducts() 

      For i As Integer = 0 To Keywords.Count - 1 

       For j As Integer = ProductSearchResults.Count - 1 To 0 Step -1 
        If ProductSearchResults(j).ProductName.ToLower.Contains(Keywords(i)) = False Then 
         ProductSearchResults.RemoveAt(j) 
        End If 
       Next 

      Next 

     End If 

     Return ProductSearchResults 

    End Function 

回答

1

這是因爲你基本上是返回指向緩存中的對象的指針集合。你可以在你的對象上實現IClonable,並且有一個函數返回一個帶有克隆對象的新集合。

Public Function GetClonedObjects() As ProductCollection 

Dim myCollection As New List(Of MyObject) 

For Each item as Product in GetProducts() 
    myCollection.Add(item.Clone) 
Loop 

Return myCollection 

End Function 

,或者創建一個屬性來保存收集

Private _clonedProducts As ProductCollection = Nothing 
    Public ReadOnly Property ClonedProducts As ProductCollection 
     Get 
     If _clonedProducts Is Nothing Then 
      _clonedProducts = New ProductCollection 
      For Each item As Product In GetAllProducts() 
      _clonedProducts.Add(item.Clone()) 
      Next 
     End If 
     Return _clonedProducts 
     End Get 
    End Property 
+0

感謝的克隆副本,這有助於。我有它的工作,但它確實減慢了我的應用程序。該頁面需要30多秒才能加載。 GetAllProducts()包含超過1000種產品,並且在我的應用程序中被調用了很多次,這就是爲什麼我要緩存它。每次它被調用時,它都會每次都克隆這個集合。有沒有一種方法可以克隆一次集合並緩存它,而不是每次調用GetAllProducts()時進行克隆? – Mark 2011-05-12 09:12:26

+0

已更新代碼以顯示如何創建本地克隆集合(並且只需執行一次克隆)。希望這有助於:) – Ben 2011-05-12 09:24:05

+0

哦,並且因爲這是ASP.Net,您可能希望根據您的範圍將我已顯示爲本地變量的內容存儲到應用程序狀態或會話狀態中。 – Ben 2011-05-12 09:26:17