此特定方案中的最佳缓存策略

时间:2012-06-21 12:47:13

标签: c# asp.net caching query-string

我正在检索一大堆新闻。

出于显而易见的原因,我希望利用此列表的缓存(运行查询不会超出必要的范围)。

我将此列表绑定到我已扩展为启用分页的转发器(在页面之间轻弹会导致页面加载,从而再次检索列表)。

复杂的是,这些新闻项目也可以通过日期从查询字符串'year'查询,该查询字符串'year'仅在按日期查询新闻项时出现。

下面是我到目前为止的伪代码(在这里粘贴实际代码需要花费太多时间来修整所有会增加混乱的位):

if(complete news items list are not cached OR querystring["year"] != null)
{
   Int year = queryString["year"] (could be null)
   Cache.Add(GetNewsItems(year));
}
else
{
   return cached newsItems;
}

问题是当新闻项页面加载时(由于分页控件的回发),查询字符串的[year]参数仍将被填充,因此将重新执行GetNewsItems。此外 - 即使主页URL(即没有查询字符串)被导航到 - 实际上仍然有新闻项目的缓存版本,所以它不会费心去尝试和检索它们 - 但它们可能在那里特定的一年所以与“全年”搜索无关。

我是否添加了一个新的缓存条目来标记最近的搜索内容? 我需要做些什么来缓存超时? 如果需要,我可以添加一个新的查询字符串(最好不要) - 这会解决问题吗?

2 个答案:

答案 0 :(得分:2)

你可以获得第一个查询的完整列表,并缓存它(假设它不是太大)?然后,对于任何后续查询,从缓存中获取数据并查询它以过滤掉您想要的年份。

也许您可以以

的形式将数据存储在缓存中
IDictionary<int, IEnumerable<NewsItem>> 

(假设一年中有多个NewsItem),其中键是年份,因此您只需检索一个字典值对即可获得一年的数据。

或者像您在样本中那样按年份缓存数据,并实施一种机制,以便每年从缓存中获取数据(如果存在)。获取所有内容后,您可以从数据存储中获取所有内容并单独缓存,也可以实现某种机制来确定缓存中缺少的年份并获取这些年份。就个人而言,我认为我会使用缓存全部并从缓存中过滤数据,以免因缓存数据过多而堵塞内存。

从缓存中获取的有用的TryGetValue模式类似于:

private bool TryGetValue<U>(string key, out U value)
    {
        object cachedValue = HttpContext.Current.Cache.Get(key);
        if (cachedValue == null)
        {
            value = default(U);
            return false;
        }
        else
        {
            try
            {
                value = (U)cachedValue;
                return true;
            }
            catch
            {
                value = default(U);
                return false;
            }
        }
    }

答案 1 :(得分:1)

不确定这对您的案例是否有帮助,但您可以将转发器添加到用户控件,并为其启用OutputCache,使POST / GET参数无效:

<%@ OutputCache Duration="100" VaryByParam="year" %>