简体   繁体   English

更新服务堆栈Redis列表

[英]Updating Service Stack Redis List

Is there a correct way to update a IRedisList? 有没有正确的方法来更新IRedisList? With the sample code below, I can modify it to remove the list, update the pizza and the re-add the list, but that feels wrong. 使用下面的示例代码,我可以修改它以删除列表,更新比萨饼并重新添加列表,但这感觉不对。 The command line documentation is pretty thourough, but it's a much bigger project than I though and I'm not entirely sure where to start looking. 命令行文档很漂亮,但这是一个比我更大的项目,我不完全确定从哪里开始寻找。

    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 
        }                   
    }

Avoid Lists: 避免列表:

Unfortunately Redis lists are not really a good choice in this situation. 不幸的是,在这种情况下,Redis列表并不是一个好的选择 I had the same issue when I started using Redis, they seem like the obvious choice ;). 当我开始使用Redis时,我遇到了同样的问题, 它们似乎是明显的选择;)。 Redis lists are useful if you are using them as a readonly set, or if you just want to pop and push, but not for modifying an item in the middle of the list. 如果您将它们用作只读集,或者只是想要弹出和推送,而不是用于修改列表中间的项目,则Redis列表非常有用。

You can "update" items in a Redis list if you know the index of the item, but it requires to remove and re-insert , and it must be by index, which determining is horribly inefficient. 如果您知道项目的索引,则可以“更新”Redis列表中的项目,但它需要删除重新插入 ,并且必须通过索引来确定非常低效。 It does so by iterating the collection, because there is no native way to do it, and this isn't a good idea. 它通过迭代集合来实现,因为没有本地方法可以做到这一点,这不是一个好主意。 This is a snippet of the IndexOf method of the RedisClientList<T> . 这是 RedisClientList<T>IndexOf方法的片段

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;
}

So to complete your code, it would be: 所以要完成你的代码,它将是:

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);
    }                   
}

But this isn't a nice way to handle it as I have said. 但正如我所说,这不是处理它的好方法。 It will retrieve the list of the other pizza objects then iterate over them until it matches the index. 它将检索其他披萨对象的列表,然后迭代它们直到它与索引匹配。 And two operations to update! 并且两个操作要更新! :( Best to avoid lists in this situation. :(最好在这种情况下避免列表。

Solution: 解:

As you are trying to access the pizza by it's Id then you can create a unique pizza key for each object, this will allow you to access the pizza directly. 当您尝试通过它获取比萨饼时,您可以为每个对象创建一个独特的比萨饼钥匙,这将允许您直接访问比萨饼。 So we might use: 所以我们可以使用:

pizzas:live:{Id}

Examples: 例子:

Create a pizza 制作披萨

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);
}

Get a pizza by Id 通过Id获取披萨

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);
}

Update a pizza by Id (Simply a GET and SET) 通过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); // Get
    pizza.State = "Delivery"; // Update
    redis.SetEntry(pizzaKey, pizza); // Save
}

Move to another "list" (maybe: when a pizza changes state) 移动到另一个“列表” (可能:当披萨改变状态时)

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);
}

Delete a pizza 删除披萨

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

List all the live pizzas 列出所有现场比萨饼

using (var redisClient = new RedisClient())
{
    var livePizzaKeys = redisClient.ScanAllKeys("pizzas:live:*").ToList();
    List<Pizza> livePizzas = redisClient.GetValues<Pizza>(livePizzaKeys);
}

I hope this helps. 我希望这有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM