Avoid listings:
Unfortunately, in this situation, Redis lists are not a good choice . I had the same problem when I started using Redis, they seem like an obvious choice;). Redis lists are useful if you use them as read-only, or just want to pop and click, but not to change an item in the middle of the list.
You can βupdateβ items in a Redis list if you know the index of the element, but it needs to be deleted and reinserted, and it must be an index whose definition is terribly inefficient. He does this by iterating through the collection, because there is no own way to do this, and this is not a good idea. This is a snippet of the IndexOf RedisClientList<T> method.
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, this 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;
But this is not a good way to handle this, as I said. It will retrieve a list of other pizza objects and then iterate over them until it matches the index. And two update operations! :( It is better to avoid lists in this situation.
Decision:
As you try to access pizza by this identifier, you can create a unique pizza key for each object, this will allow you to directly access pizza. Therefore, we can use:
pizzas:live:{Id}
Examples:
Create 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 Pizza From 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 pizza by id (just GET and 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);
Move to another "list" (possibly: when the state of pizza changes)
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); }
Remove pizza
using (var redisClient = new RedisClient()) { var pizzaKey = string.Format("pizzas:live:{0}", pizza.Id); redisClient.Remove(pizzaKey); }
List of all live pizzas
using (var redisClient = new RedisClient()) { var livePizzaKeys = redisClient.ScanAllKeys("pizzas:live:*").ToList(); List<Pizza> livePizzas = redisClient.GetValues<Pizza>(livePizzaKeys); }
Hope this helps.