Entity Framework Cache
Publié par Fabrice Michellonet sous le(s) label(s) le 5 septembre 2012Malgré la version 5 d'Entity Framework sortie il y a peu de temps, beaucoup déplorent l’absence d’un mécanisme de cache implémenté dans le Framework.
Pour ceux qui ont un peu creusé le sujet, il y a bien les "Tracing and Caching Provider Wrappers for Entity Framework" parus début 2011. Cependant, ce n’est pas la solution ultime ; à l’époque Code First n’existait pas ce qui rend cette librairie incompatible avec Code First.
Pour être tout à fait franc, le code des wrappers est disponible, je pense donc qu’en bidouillant un peu, ça doit être possible d’adapter le code pour Code First.
A l’occasion de la sortie d’EntityFramework.Patterns 0.7, je vous propose de voir ensemble comme utiliser les fonctionnalités de cache fournies par cette librairie.
Soit le contexte suivant :
public class EfContext : DbContext { public DbSet<User> Users { get; set; } public EfContext() { Database.SetInitializer(new DropCreateDatabaseIfModelChanges<EfContext>()); } }
Et l’entité User tel que :
public class User { public int Id { get; set; } public string Name { get; set; } public virtual ICollection<UserRole> UserRoles { get; set; } }
On peut facilement utiliser le cache en mémoire (il est possible d’en utiliser d’autre) fournit par EntityFramework.Patterns pour mettre en cache une collection de User.
// On charge tous les users et on les stocke dans le cache. using (EfContext ctx = new EfContext()) { IEnumerable<User> usrs = ctx.Users.ToCache(); } // autre code... // Cette fois ci, on récupère les users à partir du cache. using (EfContext ctx = new EfContext()) { IEnumerable<User> usrs = ctx.Users.FromCache(); }
Simple non ?
Pour ceux qui préfèrent éviter l’accès direct au context d’Entity Framework et qui isolent leur accès à la base dans des repository, EntityFramework.Patterns vous facilitera la tâche également.
Il vous suffit de wrapper votre Repository
using (EfContext ctx = new EfContext()) { DbContextAdapter adpt = new DbContextAdapter(ctx); IRepository<User> repo = new CacheableRepository<User>( new Repository<User>(adpt) ); // On charge tous les utilisateurs. // Par defaut le CacheableRepository va mettre en cache le resultset // en provenance de la base et le réutilisera le cas échéant plus tard. IEnumerable<User> usrs = repo.GetAll(); // autre code. // Cette fois-ci, les users proviennent du cache. Il n'y a pas d'accès en base. usrs = repo.GetAll(); }
Comme vous le voyez le CacheableRepository fait appel au cache pour vous ; et vous permet de ne pas avoir à gérer la suppression d’éléments dans le cache lorsque les éléments ont étés modifiés/supprimés/insérés etc…
Je reviendrais ultérieurement dans un prochain post sur les mécanismes avancés du cache proposés par EntityFramework.Patterns.
0 commentaires:
Enregistrer un commentaire