5

Stavo cercando Caching nella mia web api dove posso usare l'output di un metodo api (che cambia una volta in 12 ore) per chiamate secondarie e poi ho trovato this solution su SO, ma sto avendo una difficoltà nella comprensione e usando il codice seguenteMemory Cache in web api

private IEnumerable<TEntity> GetFromCache<TEntity>(string key, Func<IEnumerable<TEntity>> valueFactory) where TEntity : class 
{ 
    ObjectCache cache = MemoryCache.Default; 
    var newValue = new Lazy<IEnumerable<TEntity>>(valueFactory);    
    CacheItemPolicy policy = new CacheItemPolicy { AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(30) }; 
    //The line below returns existing item or adds the new value if it doesn't exist 
    var value = cache.AddOrGetExisting(key, newValue, policy) as Lazy<IEnumerable<TEntity>>; 
    return (value ?? newValue).Value; // Lazy<T> handles the locking itself 
} 

non sono sicuro di come chiamare e utilizzare questo metodo nel contesto di seguito? Ho un metodo Get

public IEnumerable<Employee> Get() 
    { 
     return repository.GetEmployees().OrderBy(c => c.EmpId); 
    } 

e voglio mettere in cache l'output di Get e utilizzarlo in altri miei metodi GetEmployeeById() o Search()

 public Movie GetEmployeeById(int EmpId) 
     { 
      //Search Employee in Cached Get 
     } 

     public IEnumerable<Employee> GetEmployeeBySearchString(string searchstr) 
     { 
      //Search in Cached Get 
     } 

risposta

8

ho aggiornato il vostro metodo per restituire classi invece di IEnumberable:

private TEntity GetFromCache<TEntity>(string key, Func<TEntity> valueFactory) where TEntity : class 
{ 
    ObjectCache cache = MemoryCache.Default; 
    // the lazy class provides lazy initializtion which will eavaluate the valueFactory expression only if the item does not exist in cache 
    var newValue = new Lazy<TEntity>(valueFactory);    
    CacheItemPolicy policy = new CacheItemPolicy { AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(30) }; 
    //The line below returns existing item or adds the new value if it doesn't exist 
    var value = cache.AddOrGetExisting(key, newValue, policy) as Lazy<TEntity>; 
    return (value ?? newValue).Value; // Lazy<T> handles the locking itself 
} 

quindi è possibile utilizzare questo metodo come:

public Movie GetMovieById(int movieId) 
{ 
    var cacheKey = "movie" + movieId; 
    var movie = GetFromCache<Movie>(cacheKey,() => {  
     // load movie from DB 
     return context.Movies.First(x => x.Id == movieId); 
    }); 
    return movie; 
} 

e per cercare i film

[ActionName("Search")] 
public IEnumerable<Movie> GetMovieBySearchParameter(string searchstr) 
{ 
    var cacheKey = "movies" + searchstr; 
    var movies = GetFromCache<IEnumerable<Movie>>(cacheKey,() => {    
      return repository.GetMovies().OrderBy(c => c.MovieId).ToList(); 
    }); 
    return movies; 
} 
+0

@little è fatto all'interno del metodo GetFromCache –

+0

@little si dovrebbe chiamare il repository all'interno della funzione valueFactory (verrà eseguito solo se l'oggetto non è in il cache). Guarda la mia risposta non sto chiamando un repository ma direttamente il contesto, quindi sostituisci il contesto con il repository. –

+0

@little ho aggiornato il metodo GetMovieBySearchParameter nel mio esempio e ora sta utilizzando un repository. –