2010-11-11 11 views
5

Problema

Tenemos un modelo de dominio complejo. Para evitar problemas de rendimiento, la mayor parte de la lista (generado a partir de objetos de dominio) se almacenan en caché. Todo funciona bien hasta que cambia el primer objeto de dominio. Toda lista dependiente en el caché debe actualizarse; la pregunta es: ¿cómo?Cambios en el objeto de dominio: actualizar en las listas en caché necesarias

Ejemplo

  • objeto Dominio: Casa
  • Acción: Nombre de una casa se ha cambiado
  • Efecto: todos los nombres (containts casa) Lista están fuera de la fecha, actualización necesaria

Soluciones

Sin duda, hay una manera muy fácil: después de guardar un objeto de dominio, refrescamos toda la lista de código de forma manual.

código Pseudo

repository.Save(save); 

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

Así que el problema es: tenemos que actualizar todo manualmente. Estoy buscando mejores soluciones, digamos:

  • Aspecto forma orientada w/PostSharp o Windsor
  • Observador o técnica basada en eventos
  • CQRS se trata de separar las consultas y comandos, pero esta concepción es tal vez demasiado mucho.

Cualquier idea o experiencia?

Respuesta

1

La respuesta a esta pregunta es compleja debido a que sus requisitos no están claros. ¿Pueden los datos estar añejos? Si es así, ¿cuánto tiempo?

Con base en la información limitada en su puesto, sugeriría las vistas "en caché" ser meramente una consulta sobre los datos reales. Las consultas mismas podrían actualizar periódicamente sus resultados almacenados en caché dado algún intervalo.

+0

Buenas preguntas de seguimiento. –

+0

"¿Pueden los datos estar rancios? Si es así, ¿cuánto tiempo?": Tal vez 1 hora, tal vez 1 año. El principal problema proviene de un dominio comercial volátil. – boj

0

Yo diría que, si su inserción/actualización/eliminación modifica el contenido de una de esas listas, debe volver a consultar la lista. Tengo algunas tablas de datos en caché en mi aplicación, y utilizo una colección de la estructura a continuación para mantenerlas. De esta forma, es fácil borrar todo el caché, y cuando solicito una tabla de datos en particular, verifico si existe uno en el caché que no ha expirado.

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) 

Viven en mi clase base para los objetos que consultan las bases de datos. Un ejemplo del uso de las tablas de datos almacenadas en caché es:

<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 

En el ejemplo anterior, la función comprueba la caché para ver si existe un objeto apropiado. Si lo hace, se devuelve en lugar de golpear la base de datos de nuevo. Al final, el objeto nuevo se agrega a la memoria caché.

Todo lo que tendrías que hacer sería proporcionar algunos medios para eliminar una lista en particular del caché. Luego, cuando hagas una inserción/actualización/eliminación, asegúrate de borrar el ítem apropiado.

+0

Lo siento, el código está en VB, en lugar de C#. http://www.developerfusion.com/tools/convert/csharp-to-vb/ lo convertiría por usted, si es una solución de sonido apropiada. –

+0

Gracias, pero solo se trata del almacenamiento en caché (prefiero el Bloque de aplicación de caché EntLib) y no de la actualización de caché compleja. – boj

Cuestiones relacionadas