【问题标题】:Caching search result in Web API在 Web API 中缓存搜索结果
【发布时间】:2014-12-11 10:47:46
【问题描述】:

我正在使用strathweb 在 webapi 中缓存 Get 方法,现在我想在我的另一个 webapi 方法 Search 中使用相同的缓存输出。那么如何访问缓存的 Get结果是搜索方法?如何找到缓存键以在其他方法中使用它?

    [CacheOutput(ClientTimeSpan = 300, ServerTimeSpan = 300)]
    public IEnumerable<Movie> Get()
    {
        return repository.GetEmployees().OrderBy(c => c.MovieId);
    }

【问题讨论】:

    标签: asp.net-mvc caching asp.net-web-api http-caching


    【解决方案1】:

    您可以考虑使用MemoryCache 将结果存储在内存中以便更快地访问,而不是使用OutputCache

    您可以将结果存储在缓存中(以以下示例为例:http://www.allinsight.de/caching-objects-in-net-with-memorycache/

    //Get the default MemoryCache to cache objects in memory
    private ObjectCache cache; = MemoryCache.Default;
    private CacheItemPolicy policy;
    
    public ControllerConstructor()
    {
        cache = MemoryCache.Default;
    
        policy = new CacheItemPolicy();
        policy.AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(30);
    }
    
    public IEnumerable<Movie> GetMovieBySearchParameter(string searchstr)
    {
        if (cache.Get(searchstr) != null)
        {
            return cache.Get(searchstr) as IEnumerable<Movie>;
        }
    
        // Do the search and get the results.
        IEnumerable<Movie> result = GetMovies(blah.....);
    
        // Store the results in cache.
        cache.Add(searchstr, result, policy);
    }
    

    上面很粗略(我现在没有VS在我面前尝试),但希望核心思想能够得到。

    http://www.allinsight.de/caching-objects-in-net-with-memorycache/

    【讨论】:

    • 在我的场景中使用缓存是否正确,因为可能存在大量搜索字符串,并且不会占用大量内存?
    • 您可能需要尝试一下,看看会发生什么。它真的取决于你的场景。您可以限制存储在缓存中的项目数量,这样就不会保存每个搜索字符串。这是一个可供研究的选项,如果它不适合您,请不要担心。
    【解决方案2】:

    解决此问题的最简单方法是将 OutputCache 属性添加到您的控制器。它仅在 MVC 控制器中受支持。对于 Web API 控制器,您可以使用这个 - https://github.com/filipw/AspNetWebApi-OutputCache

    以下内容会将每个搜索词的结果缓存 24 小时。但是,这种方法是幼稚的,并且仅在搜索词的数量非常少的情况下才有效。如果搜索词的数量很大(就像在这种情况下),它会增加巨大的内存压力,这将导致 ASP.NET 应用程序池回收,因此您将丢失缓存。

    [OutputCache(Duration=86400, VaryByParam="searchstr")] // for MVC
    [CacheOutput(ClientTimeSpan = 50, ServerTimeSpan = 50)] // for Web API
    [ActionName("Search")]
    public IEnumerable<Movie> GetMovieBySearchParameter(string searchstr)
    {           
    }
    

    在您的情况下,整个结果集可以缓存一次,并且可以每 24 小时更新一次。您可以查看 System.Web.HttpRuntime.Cache。当从缓存中删除项目时,它支持到期日期和回调函数。您可以将电影列表添加到缓存中,然后查询缓存。只需确保在项目过期时刷新/重新填充缓存即可。

    System.Web.HttpRuntime.Cache.Add(
                    key,
                    value,
                    null,
                    expiration,
                    Cache.NoSlidingExpiration,
                    CacheItemPriority.Normal,
                    callback);
    

    我会在控制器中引用的存储库中添加一个 CachedRepository 装饰器。在那个缓存的存储库中,我会尝试从缓存中返回数据(如果有的话)。如果不是,我会从原始来源获取并返回数据,并将其添加到缓存中。

    【讨论】:

    • WebAPI 是否支持 OutputCache 属性?
    • 啊,正确。它不是内置的,你需要这个包 - github.com/filipw/AspNetWebApi-OutputCache
    • 我已经编辑了我的问题,从搜索中调用 Get 是一种好方法吗,因为 Get 已经被缓存了?您能简单地告诉我上述上下文中的解决方案吗
    • 不,这样不行。它仅在通过管道调用该方法时才有效。但是,您始终可以直接引用缓存 - var cache = Configuration.CacheOutputConfiguration().GetCacheOutputProvider(Request); cache.Get("key");键是从控制器操作名称派生的。
    • 如何知道上述方法中的键名>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-09
    • 1970-01-01
    • 2015-03-26
    • 2011-08-27
    相关资源
    最近更新 更多