Undgå lister:
Desværre er Redis-lister ikke et godt valg i denne situation. Jeg havde det samme problem, da jeg begyndte at bruge Redis, de virker som det oplagte valg;). Redis-lister er nyttige, hvis du bruger dem som et skrivebeskyttet sæt, eller hvis du bare vil pop og push, men ikke til at ændre et element i midten af listen.
Du kan "opdatere" elementer i en Redis-liste, hvis du kender indekset for elementet, men det kræver at fjerne og indsæt igen , og det skal være efter indeks, hvilket er frygteligt ineffektivt. Det gør det ved at gentage samlingen, fordi der ikke er nogen indbygget måde at gøre det på, og det er ikke en god idé. Dette er et uddrag af IndexOf
metoden for 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;
}
Så for at fuldføre din kode, ville det være:
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);
}
}
Men det er ikke en god måde at håndtere det på, som jeg har sagt. Den vil hente listen over de andre pizzaobjekter og derefter gentage dem, indtil den matcher indekset. Og to operationer at opdatere! :( Bedst at undgå lister i denne situation.
Løsning:
Når du forsøger at få adgang til pizzaen ved hjælp af dets id, kan du oprette en unik pizzanøgle for hvert objekt, dette vil give dig direkte adgang til pizzaen. Så vi kan bruge:
pizzas:live:{Id}
Eksempler:
Opret en 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);
}
Få en pizza efter 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);
}
Opdater en pizza efter id (Simpelthen en GET og 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
}
Flyt til en anden "liste" (måske:når en pizza ændrer tilstand)
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);
}
Slet en pizza
using (var redisClient = new RedisClient())
{
var pizzaKey = string.Format("pizzas:live:{0}", pizza.Id);
redisClient.Remove(pizzaKey);
}
Læs alle de levende pizzaer
using (var redisClient = new RedisClient())
{
var livePizzaKeys = redisClient.ScanAllKeys("pizzas:live:*").ToList();
List<Pizza> livePizzas = redisClient.GetValues<Pizza>(livePizzaKeys);
}
Jeg håber, at dette hjælper.