5

我一直在尋找Caching在我的web api中,我可以使用一個api方法的輸出(在12小時內改變一次),然後我發現this solution SO,但我有一個困難在瞭解和使用下面的代碼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 
} 

我不知道如何調用,並在下面情況下使用這種方法嗎? 我有一個方法獲取

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

,我想緩存獲取和我的其他方法使用它GetEmployeeById(輸出)或Search()

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

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

回答

8

我更新了你的方法返回類,而不是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 
} 

,那麼你可以使用此方法,如:

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; 
} 

和搜索電影

[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它的GetFromCache方法 – 2014-10-28 14:07:36

+0

@little應該叫valueFactory函數內你的資料庫中完成的(它只會如果對象是不是在執行緩存)。看看我的回答,我沒有調用存儲庫,而是直接調用上下文,只是用存儲庫替換上下文。 – 2014-10-28 14:15:22

+0

@little我更新了示例中的GetMovieBySearchParameter方法,現在它正在使用存儲庫。 – 2014-10-28 14:23:19