I have a function GetAllProducts() which fetches all products from a database and stores it in the cache for future requests. This works fine, but if I then call the function e.g. ProductSearchResults = GetAllProducts(), and then modify ProductSearchResults variable, this also modifies the cache, which is very important this never happens, as the cache affects the whole website.
I understand this开发者_高级运维 is because both ProductSearchResults and the cache now have the same reference, but how do I solve the problem? Is there something that I can put in GetAllProducts() to ensure the cache always uses its own value?
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
This is because you are essentially returning a collection of pointers to the object thats in the cache. You could implement IClonable on your object and have a Function that returns a new collection with cloned objects.
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
Or Create a property to hold a cloned copy of the collection
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
精彩评论