2

我需要在缓存中存储数据列表。

有时我需要完整列表,有时我只需要查询结果并从列表中返回一项。

一项的当前逻辑是这样的:

User result;
var cachedUsers = _cache.Get<List<User>>(Constants.Cache.UsersKey);
if( cachedUsers != null)
{
    result = cachedUsers.FirstOrDefault(u => u.UserID == userID);

    if (result != null)
        return result;
}

result = GetUserFromDb(userID);

if (cachedUsers != null)
{
    cachedUsers.Add(result);
    _cache.Store(StoreMode.Set, Constants.Cache.UsersKey, cachedUsers);
}

return result;

我可以直接从缓存中访问一个元素而不加载完整的用户列表吗?我还需要在不加载完整列表并覆盖它的情况下将用户添加到缓存中。

编辑:我可以选择将项目与列表分开存储,或者使用不同的方法从头开始编写缓存。

实现此逻辑的最佳方法是什么?

4

2 回答 2

2

您可以执行的最精细的操作是检索特定密钥。如果您在该键下存储项目列表,您将获得该列表。要准确获取一个项目,您需要为每个密钥存储一个项目。

对此有多种策略,但请注意,原子性处于键级别,因此跨多个键执行操作可能会导致竞争条件。

就个人而言,我会自定义序列化您的列表(而不是依赖默认的 .NET 序列化),因为这会相当快。但这取决于在谈论更新单个密钥或请求单个密钥时“有时”有多少次。“随用随用”的常识在这里适用。

对于自定义序列化,我们使用Protobuf-net并将结果byte[]手动存储到缓存中 - 例如,缓存获取并给出 a byte[],然后我们手动进行序列化。

于 2012-08-29T10:44:57.950 回答
1

简短的回答是否定的。您缓存了整个列表,而缓存dumb并不知道您缓存了什么,只是因为您缓存了一个数据块。你必须把它全部拉回来。

但是,我曾经通过使用键的设置模式单独缓存项目然后单独缓存列表索引来解决这个问题。然而,管理起来有点乏味,然后你就有了多个对象,它们都有自己的缓存生命周期。

于 2012-08-29T10:45:06.737 回答