更新服务堆栈Redis列表

时间:2014-05-23 20:53:49

标签: c# redis servicestack

是否有更新IRedisList的正确方法?使用下面的示例代码,我可以修改它以删除列表,更新比萨饼并重新添加列表,但这感觉不对。命令行文档很漂亮,但它比我更大的项目,我不完全确定从哪里开始寻找。

    public void UpdatePizza(Pizza pizza)
    {
        using (var redisClient = new RedisClient(Host, Port))
        {
            IRedisTypedClient<Pizza> redis = redisClient.As<Pizza>();

            IRedisList<Pizza> pizzas = redis.Lists["pizzas:live"];

            var toUpdate = pizzas.First(x => x.Id == pizza.Id);

            toUpdate.State = pizza.State;

            //??How to save 
        }                   
    }

1 个答案:

答案 0 :(得分:19)

避免列表:

不幸的是,在这种情况下,Redis列表不是一个好的选择。当我开始使用Redis时,我遇到了同样的问题,它们似乎是显而易见的选择;)。如果您将它们用作只读集,或者只是想要弹出和推送,而不是用于修改列表中间的项目,则Redis列表非常有用。

如果你知道项目的索引,你可以“更新”Redis列表中的项目,但是它需要删除重新插入,它必须是通过索引,确定是非常低效的。它通过迭代集合来实现,因为没有本地方法可以做到这一点,这不是一个好主意。 IndexOf的{​​{1}}方法的This is a snippet

RedisClientList<T>

所以要完成你的代码,那就是:

public int IndexOf(T item)
{
    //TODO: replace with native implementation when exists
    var i = 0;
    foreach (var existingItem in this)
    {
        if (Equals(existingItem, item)) return i;
        i++;
    }
    return -1;
}

但正如我所说,这不是处理它的好方法。它将检索其他披萨对象的列表,然后迭代它们直到它与索引匹配。并且两个操作要更新! :(最好在这种情况下避免列表。

解决方案:

当您尝试通过它获取比萨饼时,您可以为每个对象创建一个独特的比萨饼钥匙,这样您就可以直接访问比萨饼了。所以我们可以使用:

public void UpdatePizza(Pizza pizza)
{
    using (var redisClient = new RedisClient(Host, Port))
    {
        IRedisTypedClient<Pizza> redis = redisClient.As<Pizza>();
        IRedisList<Pizza> pizzas = redis.Lists["pizzas:live"];
        var toUpdate = pizzas.First(x => x.Id == pizza.Id);
        toUpdate.State = pizza.State;

        // Update by removing & inserting (don't do it!)
        var index = pizzas.IndexOf(toUpdate);
        pizzas.Remove(index);
        pizzas.Insert(index, toUpdate);
    }                   
}

示例:

制作披萨

pizzas:live:{Id}

通过Id获取披萨

using (var redisClient = new RedisClient())
{
    IRedisTypedClient<Pizza> redis = redisClient.As<Pizza>();
    var pizzaKey = string.Format("pizzas:live:{0}", 123);
    var pizza = new Pizza { Id = 123, Type = "Mushroom", State = "Cooking" };
    redis.SetEntry(pizzaKey, pizza);
}

以Id身份更新披萨(仅限GET和SET)

using (var redisClient = new RedisClient())
{
    IRedisTypedClient<Pizza> redis = redisClient.As<Pizza>();
    var pizzaKey = string.Format("pizzas:live:{0}", pizza.Id);
    var pizza = redis.GetValue(pizzaKey);
}

转到另一个“列表”(可能:披萨改变状态时)

using (var redisClient = new RedisClient())
{
    IRedisTypedClient<Pizza> redis = redisClient.As<Pizza>();
    var pizzaKey = string.Format("pizzas:live:{0}", pizza.Id);
    var pizza = redis.GetValue(pizzaKey); // Get
    pizza.State = "Delivery"; // Update
    redis.SetEntry(pizzaKey, pizza); // Save
}

删除披萨

using (var redisClient = new RedisClient())
{
    var pizzaKey = string.Format("pizzas:live:{0}", pizza.Id);
    var deliveredKey = string.Format("pizzas:delivered:{0}", pizza.Id);
    redisClient.RenameKey(pizzaKey, deliveredKey);
}

列出所有现场比萨

using (var redisClient = new RedisClient())
{
    var pizzaKey = string.Format("pizzas:live:{0}", pizza.Id);
    redisClient.Remove(pizzaKey);
}

我希望这会有所帮助。