Web API 中的内存缓存

6
我在我的Web API中寻找缓存,以便我可以使用一个API方法的输出(每12小时更改一次)用于后续调用,然后我在SO上找到了这个解决方案,但我很难理解和使用下面的代码。
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
}

我不确定如何在下面的上下文中调用和使用此方法? 我有一个名为Get的方法

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

我希望能够缓存Get方法的输出,并在其他方法GetEmployeeById()或Search()中使用它。

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

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

11

我已经更新了你的方法,使其返回类而不是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;
}

@little 是在 GetFromCache 方法内完成的。 - Marian Ban
@little 你应该在 valueFactory 函数内调用你的 repository(它只会在对象不在缓存中时才执行)。看一下我的答案,我没有调用 repository 而是直接调用了 context,所以只需将 context 替换为 repository 即可。 - Marian Ban
@little 我在我的示例中更新了GetMovieBySearchParameter方法,现在它正在使用存储库。 - Marian Ban
@F11,你好,你想问什么? - Marian Ban
@F11 是的,请给我发送一个聊天链接。 - Marian Ban

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接