更新服务堆栈Redis列表

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

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

避免列表:

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

如果您知道项目的索引,则可以“更新”Redis列表中的项目,但它需要删除重新插入 ,并且必须通过索引,这种确定非常低效。 它是通过迭代集合来实现的,因为没有本地方法可以做到这一点,这不是一个好主意。 这是 RedisClientListIndexOf方法的片段 。

 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 redis = redisClient.As(); IRedisList 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); } } 

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

解:

当您尝试通过它的Id访问披萨时,您可以为每个对象创建一个独特的披萨键,这将允许您直接访问披萨。 所以我们可以使用:

 pizzas:live:{Id} 

例子:

制作披萨

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

通过Id获得披萨

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

通过Id (简单的GET和SET) 更新披萨

 using (var redisClient = new RedisClient()) { IRedisTypedClient redis = redisClient.As(); 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); } 

列出所有现场比萨饼

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

我希望这有帮助。