2017-08-18 3 views
2

Je suis en train de vider mon cache après mettre à jour un élément, et je l'ai essayé quelques options différentes et ne fonctionnent comme prévuFlushing MemoryCache ASP.NET Core 2

public class PostApiController : Controller 
{ 
    private readonly IPostService _postService; 
    private readonly IPostTagService _postTagService; 
    private IMemoryCache _cache; 
    private MemoryCacheEntryOptions cacheEntryOptions; 
    public PostApiController(IPostService postService, IPostTagService postTagService, IMemoryCache cache) 
    { 
     _postService = postService; 
     _postTagService = postTagService; 
     _cache = cache; 

     cacheEntryOptions = new MemoryCacheEntryOptions() 
      .SetSlidingExpiration(TimeSpan.FromDays(1)); 
    } 

    [HttpGet("{url}", Name = "GetPost")] 
    public IActionResult GetById(string url, bool includeExcerpt) 
    { 
     Post cacheEntry; 
     if (!_cache.TryGetValue($"GetById{url}{includeExcerpt}", out cacheEntry)) 
     { 
     cacheEntry = _postService.GetByUrl(url, includeExcerpt); 
     _cache.Set($"GetById{url}{includeExcerpt}", cacheEntry, cacheEntryOptions); 
     } 

     if (cacheEntry == null) 
     { 
     return NotFound(); 
     } 

     return new ObjectResult(cacheEntry); 
    } 

    [HttpPut("{id}")] 
    public IActionResult Update(int id, [FromBody] Post item) 
    { 
     if (item == null) 
     { 
     return BadRequest(); 
     } 

     var todo = _postService.GetById(id); 
     if (todo == null) 
     { 
     return NotFound(); 
     } 

     _postService.Update(item); 
     _postTagService.Sync(item.Tags.Select(a => new PostTag { PostId = item.Id, TagId = a.Id }).ToList()); 
     //Want to flush entire cache here 
     return new NoContentResult(); 
    } 

J'ai essayé de se débarrasser (MemoryCache ici mais à l'appel Api suivant, il est toujours disposé. Puisque les touches sont quelque peu dynamiques, je ne peux pas simplement obtenir les clés. Comment puis-je faire cela?

+0

Pourquoi l'appeler GetById et non GetByUrl? –

+0

De toute façon, pouvez-vous reconstruire la partie GetById {url} dans la méthode Update? –

+0

Sûrement l'élément 'todo' a une propriété' Url' que vous pouvez utiliser pour ré-insérer cet élément dans le cache? Ou même supprimer les variantes true et false includeExcerpt? – DavidG

Répondre

0

Vous pouvez stocker le dictionnaire à la place. De cette façon, vous pouvez utiliser les clés dynamiques pour les entrées et une seule clé statique pour le conteneur dictionnaire, qui peut être stockée dans le cache au lieu de stocker chaque entrée séparément.

Quelque chose comme ça:

private const string CachedEntriesKey = "SOME-STATIC-KEY"; 

[HttpGet("{url}", Name = "GetPost")] 
public IActionResult GetById(string url, bool includeExcerpt) 
{ 
    Dictionary<string, Post> cacheEntries; 
    if (!_cache.TryGetValue(CachedEntriesKey, out cacheEntries)) 
    { 
     cacheEntries = new Dictionary<string, Post>(); 
     _cache.Set(CachedEntriesKey, cacheEntries); 
    } 

    var entryKey = $"GetById{url}{includeExcerpt}"; 
    if (!cacheEntries.ContainsKey(entryKey)) 
    { 
     return NotFound(); // by the way, why you do that instead of adding to the cache? 
    } 

    return new ObjectResult(cacheEntries[entryKey]); 
} 
+0

Le problème est que la clé n'est pas statique. La clé est variable en fonction des paramètres –

+0

@IsaacLevin la façon dont j'ai proposé permet d'utiliser des clés dynamiques pour les entrées et une seule clé statique pour le conteneur de dictionnaire, qui peut être stockée en cache au lieu des entrées une par une. Avez-vous eu l'idée? –

+0

Je l'ai fait maintenant que vous l'avez formulé comme ça :) Je vais jeter un oeil –