Una forma de acelerar nuestras aplicaciones es agregando una capa de almacenamiento en caché junto a nuestra base de datos. A menudo escribimos métodos auxiliares para leer datos de nuestra base de datos, serializarlos y almacenarlos en nuestra caché. NCache Se integra con Entity Framework Core para almacenar en caché nuestras entidades con unas pocas líneas de código. Veamos cómo implementar una estrategia de caché aparte con NCache y Entity Framework Core.
Entity Framework Core no tiene un mecanismo de almacenamiento en caché integrado. Tenemos que rodar el nuestro. Pero, NCache tiene un conjunto de métodos de extensión convenientes para almacenar en caché los resultados de nuestras consultas fácilmente.
Con esta integración, aprovechamos todas las características de escalabilidad y replicación de NCache en nuestras aplicaciones de Entity Framework.
Creemos un ASP de muestra.NET Core Aplicación 6.0 para almacenar en caché una consulta de Entity Framework Core para mostrar las 10 películas mejor calificadas en un catálogo.
Cómo registrarse NCache con Entity Framework Core
Antes de comenzar, asegurémonos de tener NCache instalado. Necesitamos una edición Enterprise o Professional.
Después de crear una ASP.NET Core Aplicación Web API, instalemos EntityFrameworkCore.NCache Paquete NuGet. Si estamos usando una edición Profesional, instalamos EntityFrameworkCore.NCache.Paquete NuGet profesional en su lugar.
Para registrarse NCache con Entity Framework, en el archivo Program.cs de nuestra aplicación, escribamos,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
using Alachisoft.NCache.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; var builder = WebApplication.CreateBuilder(args); builder.Services.AddDbContext(options => { var config = builder.Configuration; var connectionString = config.GetConnectionString("Default"); // Configure NCache with Entity Framework // We need a cacheId and database type NCacheConfiguration.Configure(cacheId: "demoCache", DependencyType.SqlServer); NCacheConfiguration.ConfigureLogger(); options.UseSqlServer(connectionString); }); builder.Services.AddControllers(); var app = builder.Build(); app.MapControllers(); app.Run(); |
Parece un ASP normal..NET Core aplicación que utiliza Entity Framework Core, excepto dos métodos: Configure() y ConfigureLogger() de NCacheConfiguración.
Con el método Configure(), especificamos el cacheId y el tipo de base de datos. Estamos usando demoCache, la instancia de caché predeterminada y DependencyType.SqlServer. Por supuesto, deberíamos leer el cacheId de un archivo de configuración.
En este ejemplo, solo usamos un cacheId y un tipo de base de datos, pero también podemos pasar opciones de configuración adicionales como reintentos y tiempos de espera.
Y ConfigureLogger() configura la abstracción de registro subyacente desde ASP.NET Core.
Cómo insertar y almacenar en caché los resultados de Entity Framework Core en NCache
Después de registrarse NCache en Entity Framework Core, estamos leyendo para comenzar a almacenar en caché nuestras películas.
Resultados principales de Entity Framework de almacenamiento en caché
Creemos una clase MoviesController para leer las 10 mejores películas y almacenarlas en caché NCache. Como esto,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
using Alachisoft.NCache.EntityFrameworkCore; using Microsoft.AspNetCore.Mvc; namespace Movies.Controllers; [ApiController] [Route("[controller]")] public class MoviesController : ControllerBase { private readonly DatabaseContext _database; public MoviesController(DatabaseContext database) { _database = database; } [HttpGet] public async Task<IEnumerable> Get() { return await _database .Movies .OrderByDescending(m => m.Rating) .ThenBy(m => m.ReleaseYear) .Take(10) .FromCacheAsync(new CachingOptions { StoreAs = StoreAs.Collection }); } } |
NCache trae nuevos métodos de extensión además de los métodos existentes de Entity Framework Core.
Después de una consulta LINQ para recuperar 10 películas ordenadas por clasificación y año de lanzamiento, agregamos un nuevo método: FromCacheAsync().
FromCacheAsync()
almacena en caché el resultado de nuestra consulta LINQ y lo devuelve. Si nuestro caché no tiene este resultado, va a la base de datos y luego lo almacena en caché. Si no podemos conectarnos a nuestro servidor de caché, NCache devolverá el resultado de nuestra base de datos. Luego seguirá intentando llenar el caché con nuestro resultado.
Cuando usamos FromCacheAsync(), pasamos un parámetro CachingOptions, indicando NCache para almacenar en caché el resultado de nuestra consulta como un todo en lugar de entradas separadas. Hay más opciones para especificar vencimientos y prioridades.
FromCacheAsyn() tiene una alternativa sincrónica FromCache()
. A diferencia de su versión asíncrona, FromCache() devuelve la clave de caché del nuevo elemento como parámetro de salida.
LoadIntoCache y FromCacheOnly
Además de FromCache() y FromCacheAsync(), NCache tiene otros dos métodos: LoadIntoCache() y FromCacheOnly().
LoadIntoCache() sobrescribe los resultados almacenados en caché en cada llamada. Funciona como FromCache() con una pérdida de caché en cada llamada. Este método es más adecuado para datos que cambian con frecuencia y escenarios en los que siempre necesitamos una copia nueva de nuestros datos.
FromCacheOnly() no llama a la base de datos subyacente. Siempre va al servidor de caché. FromCacheOnly() admite funciones de agregación como Sum, Min y Max. Pero también tiene algunas limitaciones. Por ejemplo, FromCacheOnly() no admite múltiples proyecciones o uniones en la expresión LINQ.
Por supuesto, estos dos últimos métodos también tienen alternativas asíncronas.
Insertar elementos
Después de almacenar en caché los resultados de nuestras consultas LINQ, veamos cómo insertar elementos.
En MoviesController
clase, escribamos un nuevo método para agregar una película. Como esto,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// In the same MoviesController.cs file [HttpPost] public async Task Post([FromBody] AddMovie request) { var newMovie = new Movie( name: request.Name, releaseYear: request.ReleaseYear, rating: request.Rating); _database.Movies.Add(newMovie); await _database.SaveChangesAsync(); var options = new CachingOptions { StoreAs = StoreAs.SeperateEntities }; Cache cache = _database.GetCache(); cache.Insert(newMovie, out _, options); } |
Después de insertar una película como lo hacemos normalmente con SaveChangesAsync(), obtenemos una referencia a nuestro caché con GetCache(). Luego, usando la misma referencia de objeto, insertamos una nueva película con Insert() pasando CachingOptions. También podemos pasar una prioridad, un identificador de consulta y tiempos de vencimiento.
Cuando usamos Insert() si el caché ya contiene un elemento, en su lugar se actualiza.
Observe que insertamos el nuevo elemento en nuestro caché justo después de llamar a SaveChangesAsync(), sin volver a la base de datos para recuperarlo y luego almacenarlo en caché. Eso ahorra un viaje de ida y vuelta a nuestra base de datos por cada objeto que queremos insertar.
Conclusión
Así es como podemos usar NCache en nuestras aplicaciones Entity Framework Core. Podemos comenzar a almacenar en caché nuestras entidades con algunos cambios en nuestras consultas LINQ existentes. Sólo necesitamos ampliar nuestra configuración de Entity Framework.
y utilice FromCache() y sus alternativas. En esta publicación, almacenamos en caché e insertamos elementos, pero también podemos remove elementos de nuestra caché por un nombre de clave, identificador de consulta o una referencia de objeto.
Recordemos que, para consultas LINQ complejas, usemos FromCache(). Para datos actualizados con frecuencia, usemos LoadIntoCache(). Y para datos de sólo lectura, FromCacheOnly().
Aparte de la estrategia de caché aparte que seguimos en esta publicación, NCache admite otras estrategias y patrones de almacenamiento en caché como lectura y escritura. Y se integra con el ASP.NET Core marco para soportar el almacenamiento en caché del estado de sesión.
Para seguir el código que escribimos en esta publicación, consulte mi NCache Repositorio de demostración en GitHub.