Une façon d'accélérer nos applications consiste à ajouter une couche de mise en cache à côté de notre base de données. Nous écrivons souvent des méthodes d'assistance pour lire les données de notre base de données, les sérialiser et les stocker dans notre cache. NCache s'intègre à Entity Framework Core pour mettre en cache nos entités avec quelques lignes de code. Voyons comment mettre en œuvre une stratégie de cache-side avec NCache et Entity Framework Core.
Entity Framework Core ne dispose pas de mécanisme de mise en cache intégré. Nous devons rouler les nôtres. Mais, NCache dispose d'un ensemble de méthodes d'extension pratiques pour mettre facilement en cache les résultats de nos requêtes.
Avec cette intégration, nous profitons de toutes les fonctionnalités d'évolutivité et de réplication de NCache dans nos applications Entity Framework.
Créons un exemple d'ASP.NET Core 6.0 pour mettre en cache une requête Entity Framework Core afin d'afficher les 10 films les mieux notés dans un catalogue.
Comment s'inscrire NCache avec Entity Framework Core
Avant de commencer, assurons-nous d'avoir NCache installée. Nous avons besoin d’une édition Entreprise ou Professionnelle.
Après avoir créé un ASP.NET Core Application API Web, installons EntityFrameworkCore.NCache Paquet NuGet. Si nous utilisons une édition Professionnelle, nous installons EntityFrameworkCore.NCache.Professional NuGet à la place.
Enregistrer NCache avec Entity Framework, dans le fichier Program.cs de notre application, écrivons,
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(); |
Cela ressemble à un ASP normal.NET Core application qui utilise Entity Framework Core, à l'exception de deux méthodes : Configure() et ConfigureLogger() de NCacheConfiguration.
Avec la méthode Configure(), nous spécifions le cacheId et le type de base de données. Nous utilisons demoCache, l'instance de cache par défaut et DependencyType.SqlServer. Bien sûr, nous devrions lire le cacheId à partir d’un fichier de configuration.
Dans cet exemple, nous utilisons uniquement un cacheId et un type de base de données, mais nous pouvons également transmettre options de configuration supplémentaires comme les tentatives et les délais d'attente.
Et ConfigureLogger() configure l'abstraction de journalisation sous-jacente à partir d'ASP.NET Core.
Comment insérer et mettre en cache les résultats d'Entity Framework Core dans NCache
Après l'enregistrement NCache dans Entity Framework Core, nous lisons pour commencer à mettre en cache nos films.
Résultats principaux de Caching Entity Framework
Créons une classe MoviesController pour lire les 10 meilleurs films et les mettre en cache NCache. Comme ça,
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 apporte de nouvelles méthodes d'extension en plus des méthodes Entity Framework Core existantes.
Après une requête LINQ pour récupérer 10 films triés par classement et année de sortie, nous ajoutons une nouvelle méthode : FromCacheAsync().
FromCacheAsync()
met en cache le résultat de notre requête LINQ et le renvoie. Si notre cache n'a pas ce résultat, il va dans la base de données puis le met en cache. Si nous ne parvenons pas à nous connecter à notre serveur de cache, NCache renverra le résultat de notre base de données. Ensuite, il réessayera de remplir le cache avec notre résultat.
Lors de l'utilisation de FromCacheAsync(), nous passons un paramètre CachingOptions, indiquant NCache pour mettre en cache le résultat de notre requête dans son ensemble au lieu d'entrées séparées. Il y a plus d'options pour spécifier les expirations et les priorités.
FromCacheAsyn() a une alternative synchrone FromCache()
. Contrairement à sa version asynchrone, FromCache() renvoie la clé de cache du nouvel élément en tant que paramètre de sortie.
LoadIntoCache et FromCacheOnly
Outre FromCache() et FromCacheAsync(), NCache a deux autres méthodes : LoadIntoCache() et FromCacheOnly().
LoadIntoCache() écrase les résultats mis en cache à chaque appel. Cela fonctionne comme FromCache() avec un manque de cache à chaque appel. Cette méthode est la mieux adaptée aux données fréquemment modifiées et aux scénarios dans lesquels nous avons toujours besoin d'une nouvelle copie de nos données.
FromCacheOnly() n'appelle pas la base de données sous-jacente. Il va toujours au serveur de cache. FromCacheOnly() prend en charge les fonctions d'agrégation telles que Sum, Min et Max. Mais il a aussi quelques limitations. Par exemple, FromCacheOnly() ne prend pas en charge plusieurs projections ou jointures dans l'expression LINQ.
Bien entendu, ces deux dernières méthodes ont également des alternatives asynchrones.
Insérer des éléments
Après avoir mis en cache les résultats de nos requêtes LINQ, voyons comment insérer des éléments.
Dans le MoviesController
classe, écrivons une nouvelle méthode pour ajouter un film. Comme ça,
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); } |
Après avoir inséré un film comme nous le faisons habituellement avec SaveChangesAsync(), nous obtenons une référence à notre cache avec GetCache(). Ensuite, en utilisant la même référence d'objet, nous insérons un nouveau film avec Insert() en passant les CachingOptions. Nous pouvons également transmettre une priorité, un identifiant de requête et des délais d'expiration.
Lorsque nous utilisons Insert() si le cache contient déjà un élément, il est mis à jour à la place.
Notez que nous avons inséré le nouvel élément dans notre cache juste après avoir appelé SaveChangesAsync(), sans retourner dans la base de données pour le récupérer puis le mettre en cache. Cela permet d'économiser un aller-retour vers notre base de données pour chaque objet que nous souhaitons insérer.
Conclusion
C'est ainsi que nous pouvons utiliser NCache dans nos applications Entity Framework Core. Nous pouvons commencer à mettre en cache nos entités avec quelques modifications de nos requêtes LINQ existantes. Il nous suffit d'étendre notre configuration Entity Framework
et utilisez FromCache() et ses alternatives. Dans cet article, nous avons mis en cache et inséré des éléments, mais nous pouvons également supprimez éléments de notre cache par un nom de clé, un identifiant de requête ou une référence d'objet.
Rappelons que pour les requêtes LINQ complexes, utilisons FromCache(). Pour les données fréquemment mises à jour, utilisons LoadIntoCache(). Et pour les données en lecture seule, FromCacheOnly().
Outre la stratégie Cache-aside que nous avons suivie dans cet article, NCache prend en charge d'autres stratégies et modèles de mise en cache tels que la lecture et l'écriture. Et il s'intègre à l'ASP.NET Core cadre pour prendre en charge la mise en cache de l’état de session.
Pour suivre le code que nous avons écrit dans cet article, consultez mon NCache Référentiel de démonstration sur GitHub.