2017-08-18 3 views
2

Ich versuche, meine Cache zu leeren, nachdem ich einen Artikel aktualisieren, und ich habe ein paar verschiedene Optionen und keiner versucht, arbeiten wie erwartetFlushing Memory 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(); 
    } 

ich versucht habe zu entsorgen () MemoryCache hier aber beim nächsten Api-Aufruf ist es immer noch entsorgt. Da die Tasten etwas dynamisch sind, kann ich nicht einfach die Schlüssel bekommen. Wie kann ich das tun?

+0

Warum nennen es GetById und GetByUrl nicht? –

+0

Wie auch immer, können Sie den GetById {url} -Teil in der Update-Methode rekonstruieren? –

+0

Sicher hat das 'todo'-Objekt eine 'Url'-Eigenschaft, die Sie verwenden können, um dieses Element wieder in den Cache einzufügen? Oder entfernen Sie beide 'includeExcerpt' True und False-Varianten? – DavidG

Antwort

0

Sie können stattdessen das Wörterbuch speichern. Auf diese Weise können Sie die dynamischen Schlüssel für Einträge und einen einzelnen statischen Schlüssel für den Wörterbuchcontainer verwenden, die im Cache gespeichert werden können, anstatt jeden Eintrag einzeln zu speichern.

So etwas:

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

Problem ist, dass der Schlüssel nicht statisch ist. Schlüssel ist variabel basierend auf params –

+0

@IsaacLevin die Art, wie ich vorgeschlagen, ermöglicht dynamische Schlüssel für Einträge und einen einzigen statischen Schlüssel für den Wörterbuch-Container, die Cache statt Einträge nacheinander gespeichert werden können. Hast du die Idee? –

+0

Ich tat jetzt, dass Sie es so formulierten :) Ich werde einen Blick –