域对象更改 - 刷新所需的缓存列表

时间:2010-11-11 18:23:14

标签: c# business-objects

问题

我们有一个复杂的域模型。为避免性能问题,大多数列表(从域对象生成)都已缓存。在第一个域对象发生变化之前,一切正常。必须刷新缓存中的所有依赖列表 - 问题是:如何?

实施例

  • 域对象:众议院
  • 操作:房屋名称已更改
  • 效果:所有列表(包含房屋名称)已过期,需要刷新

解决方案

毫无疑问,有一种非常简单的方法:保存域对象后,我们手动刷新代码中的所有列表。

伪码

repository.Save(save);

cacheManager.Invalidate("HouseList");
cacheManager.Invalidate("OrderedHouseList");
cacheManager.Invalidate("HousecombinedWithResidentsList");
...

所以问题是:我们必须手动刷新所有内容。我正在寻找更好的解决方案,让我们说:

  • 面向方面的方式w / PostSharp或Windsor
  • 基于观察者或事件的技术
  • CQRS它是关于分离查询和命令,但这个概念可能太多了。

任何想法或经验?

2 个答案:

答案 0 :(得分:1)

这个问题的答案很复杂,因为你的要求不清楚。数据可以陈旧吗?如果是这样,多久?

根据您帖子中的有限信息,我建议“缓存”视图仅仅是对真实数据的查询。在某个时间间隔内,查询本身可以定期刷新缓存的结果。

答案 1 :(得分:0)

我想说,如果你的插入/更新/删除修改了其中一个列表的内容,你应该重新查询列表。我的应用程序中有一些缓存的数据表,我使用下面的结构集合来维护它们。这样,很容易清除整个缓存,当我要求一个特定的数据表时,我会检查缓存中是否存在一个未过期的数据。

Protected Structure CachedDT

    #Region "Local Variables"

    Public TheDT As DataTable
    Public TheExpirationTime As DateTime
    Public TheUniqueIdentifier As String

    #End Region 'Local Variables

End Structure

Protected cCachedDTs As Dictionary(Of String, CachedDT) = New Dictionary(Of String, CachedDT)

这些存在于我的基类中,用于查询数据库的对象。使用缓存数据表的一个示例是:

    <System.Diagnostics.DebuggerStepThrough> _
    Public Overrides Function GetPermissionsSystem(ByVal SystemUserName As String) As DataTable
        Try
            Dim oCmd As New SqlCommand
            Dim aDpt As New SqlDataAdapter
            Dim aDst As New DataSet
            Dim theCached As CachedDT
            Dim theCacheName As String = "GetPermissionsSystem|" & SystemUserName
            If cCachedDTs.ContainsKey(theCacheName) Then
                theCached = cCachedDTs.Item(theCacheName)
                If theCached.TheExpirationTime < DateTime.Now Then
                    cCachedDTs.Remove(theCacheName)
                Else
                    Return theCached.TheDT
                End If
            End If
            With oCmd
                .Connection = MyBase.Conn
                .CommandType = CommandType.StoredProcedure
                .CommandTimeout = MyBase.TimeoutShort
                .CommandText = Invoicing.GetPermissionsSystem
                .Parameters.Add(GP("@SystemUserName", SystemUserName))
            End With
            aDpt.SelectCommand = oCmd
            aDpt.Fill(aDst)
            theCached = New CachedDT
            With theCached
                .TheUniqueIdentifier = theCacheName
                .TheExpirationTime = DateTime.Now.AddSeconds(10)
                .TheDT = aDst.Tables(0)
            End With
            cCachedDTs.Add(theCached.TheUniqueIdentifier, theCached)
            Return aDst.Tables(0)
        Catch sqlex As SqlException
            MyBase.HandelEX(sqlex)
        Catch ex As Exception
            MyBase.HandleEX(ex)
        Finally
            MyBase.CloseConn()
        End Try
    End Function

在上面的示例中,该函数检查缓存以查看是否存在适当的对象。如果是,则返回而不是再次访问数据库。最后,将新鲜对象添加到缓存中。

您所要做的就是提供一些从缓存中删除特定列表的方法。然后,当您执行插入/更新/删除时,请确保清除相应的项目。