C# 域对象更改-需要刷新缓存列表 问题

C# 域对象更改-需要刷新缓存列表 问题,c#,business-objects,C#,Business Objects,我们有一个复杂的领域模型。为了避免性能问题,大多数列表(由域对象生成)都被缓存。在第一个域对象更改之前,一切都正常工作。缓存中的所有依赖列表都必须刷新-问题是:如何刷新 例子 域对象:房屋 行动:房子的名称已更改 效果:所有列表(包含房屋名称)都已过期,需要刷新 解决 毫无疑问,有一种非常简单的方法:保存域对象后,我们手动刷新代码中的所有列表 伪代码 repository.Save(save); cacheManager.Invalidate("HouseList"); cacheMana

我们有一个复杂的领域模型。为了避免性能问题,大多数列表(由域对象生成)都被缓存。在第一个域对象更改之前,一切都正常工作。缓存中的所有依赖列表都必须刷新-问题是:如何刷新

例子
  • 域对象:房屋
  • 行动:房子的名称已更改
  • 效果:所有列表(包含房屋名称)都已过期,需要刷新
解决 毫无疑问,有一种非常简单的方法:保存域对象后,我们手动刷新代码中的所有列表

伪代码

repository.Save(save);

cacheManager.Invalidate("HouseList");
cacheManager.Invalidate("OrderedHouseList");
cacheManager.Invalidate("HousecombinedWithResidentsList");
...
所以问题是:我们必须手动刷新所有内容。我正在寻找更好的解决方案,比如:

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

有什么想法或经验吗?

这个问题的答案很复杂,因为您的需求不清楚。数据会过时吗?如果是,需要多长时间


基于你文章中的有限信息,我建议“缓存”视图仅仅是对真实数据的查询。查询本身可以在一定的时间间隔内定期刷新缓存的结果。

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

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
_
公共重写函数GetPermissionsSystem(ByVal SystemUserName作为字符串)作为DataTable
尝试
Dim oCmd作为新的SqlCommand
Dim aDpt作为新的SqlDataAdapter
Dim aDst作为新数据集
暗淡的颜色被刻成纪念印
将CacheName设置为String=“GetPermissionsSystem |”&系统用户名
如果ccachedts.ContainsKey(缓存名),则
缓存=ccachedts.Item(缓存名称)
如果cached.TheExpirationTime
在上面的示例中,函数检查缓存以查看是否存在适当的对象。如果是,则返回该值,而不是再次访问数据库。最后,将新对象添加到缓存中


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

很抱歉,代码是用VB编写的,而不是用C#编写的。如果这是一个合适的解决方案,我会为您转换它。谢谢,但这只是关于缓存(我更喜欢EntLib缓存应用程序块),而不是关于复杂的缓存刷新。“数据会过时吗?如果会,多长时间?”:可能1小时,可能1年。主要问题来自不稳定的业务领域。