Hoy después de unos días, que parecieron hacerse eternos, les traigo un nuevo post que compartir con ustedes, esta vez pondremos la vista en el desempeño de nuestras aplicaciones, en este caso aplicaciones que utilicen Entity Framework como tecnología de acceso a datos (conexión a base de datos).

Que es un cache de segundo nivel? Y el primer nivel?

Ok, antes de implementar un cache de segundo nivel, debemos entender que es y donde encaja el cache de primer nivel.

EF

Cache de primer nivel, es el empleado por el proceso interno de Entity Framework a nivel del contexto y de transacción que le permiten ejecutar la misma consulta de manera más rápida la segunda vez(un comportamiento que de seguro han notado).

Cache de segundo nivel, este es el cache que implementaremos, el cual se encontrara entre la base de datos y Entity Framework, usando un concepto muy interesante que encontramos en la versión 6, un interceptor.

Veamos una forma fácil de implementar el cache de segundo nivel con Entity Framework 6

Gracias al diseño de Entity Framework 6, que posee interceptores han surgido algunos paquetes de Nuget para facilitarnos la tarea de implementar cache en Entity Framework. El paquete que usaremos se llama EntityFramework.Cache.

  1. Para ilustrar el uso iniciaremos con una aplicación sencilla de consola. Usare para este ejemplo la base de datos AdventureWorks.

  1. En nuestra aplicación de consola mediremos los tiempos de hacer una consulta de los primeros 100 empleados (tabla HumanResources.Employee). En esta aplicación mediré el tiempo de hacer la consulta dos veces.


Los resultados podemos verlo, al ejecutar la aplicación.

  1. Podemos ver como la segunda vez demora mucho menos, esto es debido a que Entity Framework tiene un proceso de inicialización que le cuesta un tiempo considerable la primera vez. La segunda vez le toma 79877 ticks que equivale a 7ms. Si desean implementarlo siguiendo este post pueden bajar el código del ejemplo que se muestra aquí de GitHub https://github.com/jesulink2514/EF.CacheSample/tree/87ff444a8e2ace17fca36c683d112223dc82c096.

  2. Ahora para activar el cache en EntityFramework, instalaremos el paquete.

    PM> Install-Package EntityFramework.Cache

  3. Lo único que debemos hacer para habilitarlo es crear un archivo de configuración. Aquí se agrega el interceptor, se configura la política de cache, y la implementación del proveedor de cache. Para este ejemplo usaremos el proveedor que viene con el paquete, InMemoryCache.

   
        namespace EF.CacheSample
        {
            public class Configuration : DbConfiguration
            {
                public Configuration()
                {
                 var transactionHandler = new CacheTransactionHandler(new InMemoryCache());                    
                 AddInterceptor(transactionHandler);
                 var cachingPolicy = new CachingPolicy();
                 Loaded+=(sender, args)=> args.ReplaceService((s, _) => new CachingProviderServices(s,transactionHandler,cachingPolicy));
            }
        }
    }
  1. Ahora probemos cómo funciona el cache. Y que tiempos tenemos esta vez.

    Esta vez podemos ver cómo 15723 ticks en ejecutar la segunda consulta ya que esta vez la tenemos en caché, tiempo que equivale a 1 ms.

  2. Como podemos mejorar el desempeño de nuestras consultas repetitivas puede ser realmente sencillo con el paquete de cache de Entity Framework (pueden bajar el código completo en https://github.com/jesulink2514/EF.CacheSample).

Resultados promedios
##Comparativa
Total time sin cache:0074018 ticks
Total time con cache:0016608 ticks

Conclusiones

Podemos implementar el cache en Entity Framework de forma sencilla basándonos en los interceptores que nos presenta la API y algunos paquetes. Este paquete en particular (EntityFramework.Cache) nos permite sobrescribir el proveedor de cache y la política del mismo a través de código. Lo interesante de este paquete es que automáticamente invalida el cache cuando utilizamos Entity Framework para actualizar, agregar o eliminar un registro ;).