对象引用和缓存

时间:2011-05-11 12:08:42

标签: asp.net vb.net

我有一个GetAllProducts()函数,它从数据库中提取所有产品并将其存储在缓存中以供将来请求使用。这工作正常,但如果我然后调用该函数,例如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 个答案:

答案 0 :(得分:1)

这是因为您实际上是返回指向缓存中对象的指针集合。您可以在对象上实现IClonable,并使用一个Function来返回带有克隆对象的新集合。

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