1

我正在将 Massive micro-ORM 用于一个新项目。我添加了一些缓存,这一切似乎都起作用了——直到我意识到缓存对象(动态)仍在查询数据库。这扼杀了缓存的全部意义。

将结果集与数据库断开连接的最简单方法是什么。几乎所有的调用都是只读的。

我正在使用这样的代码来查询记录:

public static dynamic GetActive()
{
    return Caching.LoadFromCache("Units_GetActive", 120,
        () =>
        {
            dynamic tbl = new Units();
            return tbl.Find(Enabled: 1, orderby: "SortOrder");
        });
}

我的缓存代码如下所示:

public static dynamic LoadFromCache(string cacheKey, int secondsToCache, Func<object> query)
{
    object tocache = null;

    // result will always get the value here
    // tocache will only have the value when it was pulled from our method
    object result = MemoryCache.Default[cacheKey] ?? (tocache = query.Invoke());

    if (secondsToCache > 0)
    {
        if (tocache != null) // only save to cache if it wasn't there
            MemoryCache.Default.Add(cacheKey, tocache, DateTime.UtcNow.AddSeconds(secondsToCache));
    }
    else
    {
        // remove from cache only if secondsToCache was zero or less
        MemoryCache.Default.Remove(cacheKey);
    }

    return result;
}

缓存代码有效。问题是返回的动态对象 ( IEnumerable<dynamic>) 打开了另一个与数据库的连接。

想法?

4

1 回答 1

0

蒂姆·梅多拉(Tim Medora)的想法是正确的。

我将缓存代码更改为:

public static dynamic LoadFromCache(string cacheKey, int secondsToCache, Func<object> query)
{
    object tocache = null;

    // result will always get the value here
    // tocache will only have the value when it was pulled from our method
    object result = MemoryCache.Default[cacheKey] ?? (tocache = query.Invoke());

    if (secondsToCache > 0)
    {
        // If this came from Massive, we need to get the list instead of opening a 
        // database connection each time we enumerate.  I check the type, because other things
        // are stored.
        if (tocache is IEnumerable<dynamic>)
        {
            tocache = ((IEnumerable<dynamic>)tocache).ToList<dynamic>();
            result = tocache;
        }

        if (tocache != null) // only save to cache if it wasn't there
            MemoryCache.Default.Add(cacheKey, tocache, DateTime.UtcNow.AddSeconds(secondsToCache));
    }
    else
    {
        // remove from cache only if secondsToCache was zero or less
        MemoryCache.Default.Remove(cacheKey);
    }

    return result;
}

ToList<dynamic>()是关键部分。它现在似乎按预期工作。ToList<T>是命名空间中的扩展方法System.Linq

于 2014-05-09T19:54:54.850 回答