Vyhnout se seznamům:
Bohužel seznamy Redis nejsou ve skutečnosti dobrou volbou v této situaci. Měl jsem stejný problém, když jsem začal používat Redis, připadají mi jako jasná volba;). Seznamy Redis jsou užitečné, pokud je používáte jako sadu pouze pro čtení, nebo pokud chcete jen vyskakovat a tlačit, ale ne pro úpravu položky uprostřed seznamu.
Položky v seznamu Redis můžete "aktualizovat", pokud znáte index položky, ale vyžaduje to odstranit a znovu vložte a musí to být podle indexu, což je určování strašně neefektivní. Dělá to iterací kolekce, protože neexistuje žádný nativní způsob, jak to udělat, a to není dobrý nápad. Toto je úryvek z IndexOf
metoda 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;
}
Pro dokončení kódu by to bylo:
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);
}
}
Ale to není dobrý způsob, jak to zvládnout, jak jsem řekl. Získá seznam ostatních objektů pizzy a poté je bude iterovat, dokud nebude odpovídat indexu. A dvě operace k aktualizaci! :( V této situaci je nejlepší se seznamům vyhnout.
Řešení:
Když se pokoušíte získat přístup k pizze pomocí jejího ID, můžete pro každý objekt vytvořit jedinečný klíč na pizzu, což vám umožní přímý přístup k pizze. Můžeme tedy použít:
pizzas:live:{Id}
Příklady:
Vytvořte pizzu
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);
}
Získejte pizzu podle 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);
}
Aktualizovat pizzu podle ID (Jednoduché GET a 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
}
Přesunout na jiný „seznam“ (možná:když pizza změní stav)
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);
}
Smazat pizzu
using (var redisClient = new RedisClient())
{
var pizzaKey = string.Format("pizzas:live:{0}", pizza.Id);
redisClient.Remove(pizzaKey);
}
Seznam všech živých pizz
using (var redisClient = new RedisClient())
{
var livePizzaKeys = redisClient.ScanAllKeys("pizzas:live:*").ToList();
List<Pizza> livePizzas = redisClient.GetValues<Pizza>(livePizzaKeys);
}
Doufám, že to pomůže.