Listen vermeiden:
Leider sind Redis-Listen keine wirklich gute Wahl in dieser Situation. Ich hatte das gleiche Problem, als ich anfing, Redis zu verwenden, sie scheinen die offensichtliche Wahl zu sein;). Redis-Listen sind nützlich, wenn Sie sie als schreibgeschützten Satz verwenden oder wenn Sie nur Pop und Push verwenden möchten, aber nicht, um ein Element in der Mitte der Liste zu ändern.
Sie können Elemente in einer Redis-Liste "aktualisieren", wenn Sie den Index des Elements kennen, aber es muss entfernt werden und erneut einfügen , und es muss ein Index sein, dessen Bestimmung schrecklich ineffizient ist. Dies geschieht durch Iterieren der Sammlung, da es keine native Möglichkeit gibt, dies zu tun, und dies keine gute Idee ist. Dies ist ein Ausschnitt des IndexOf
-Methode der 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;
}
Um Ihren Code zu vervollständigen, wäre es also:
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);
}
}
Aber das ist keine schöne Art, damit umzugehen, wie ich gesagt habe. Es ruft die Liste der anderen Pizza-Objekte ab und iteriert dann über sie, bis sie mit dem Index übereinstimmt. Und zwei Operationen zum Aktualisieren! :( Vermeiden Sie in dieser Situation am besten Listen.
Lösung:
Wenn Sie versuchen, über die ID auf die Pizza zuzugreifen, können Sie für jedes Objekt einen eindeutigen Pizzaschlüssel erstellen, mit dem Sie direkt auf die Pizza zugreifen können. Wir könnten also verwenden:
pizzas:live:{Id}
Beispiele:
Erstellen Sie eine 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);
}
Holen Sie sich eine Pizza von 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);
}
Aktualisieren Sie eine Pizza nach ID (Einfach ein GET und 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
}
Zu einer anderen "Liste" wechseln (vielleicht:wenn eine Pizza ihren Zustand ändert)
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);
}
Pizza löschen
using (var redisClient = new RedisClient())
{
var pizzaKey = string.Format("pizzas:live:{0}", pizza.Id);
redisClient.Remove(pizzaKey);
}
Alle Live-Pizzen auflisten
using (var redisClient = new RedisClient())
{
var livePizzaKeys = redisClient.ScanAllKeys("pizzas:live:*").ToList();
List<Pizza> livePizzas = redisClient.GetValues<Pizza>(livePizzaKeys);
}
Ich hoffe, das hilft.