3

我正在检索一大堆新闻项目。

出于明显的原因,我想利用此列表的缓存(运行查询超过必要不会这样做)。

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

复杂之处在于,这些新闻项目也可以从查询字符串“年”中按日期查询,该查询字符串仅在按日期查询新闻项目时才出现。

下面是我到目前为止所拥有的伪代码(在此处粘贴真实代码将花费太多时间来修剪所有只会增加混乱的位):

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(即没有查询字符串)被导航到 - 实际上仍然有新闻项目的缓存版本,因此它不会费心尝试检索它们 - 但它们可能在特定年份存在因此与“所有年份”的搜索无关。

我是否添加一个新的缓存条目来标记最近完成的搜索?我必须在这里做哪些考虑来缓存超时?如果需要(最好不要),我可以添加一个新的查询字符串 - 这会解决问题吗?

4

2 回答 2

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;
            }
        }
    }
于 2012-06-21T13:22:17.567 回答
1

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

<%@ OutputCache Duration="100" VaryByParam="year" %>
于 2012-06-21T12:55:50.840 回答