Lijsten vermijden:
Helaas zijn Redis-lijsten niet echt een goede keuze in deze situatie. Ik had hetzelfde probleem toen ik Redis begon te gebruiken, lijkt een voor de hand liggende keuze;). Redis-lijsten zijn handig als u ze gebruikt als een alleen-lezen set, of als u gewoon wilt pop-uppen en pushen, maar niet voor het wijzigen van een item in het midden van de lijst.
U kunt items in een Redis-lijst "bijwerken" als u de index van het item kent, maar het moet verwijderen en opnieuw invoegen , en het moet per index zijn, welke bepaling vreselijk inefficiënt is. Het doet dit door de verzameling te herhalen, omdat er geen native manier is om dit te doen, en dit is geen goed idee. Dit is een fragment van de IndexOf
methode van de 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;
}
Dus om uw code te voltooien, zou het zijn:
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);
}
}
Maar dit is geen leuke manier om ermee om te gaan, zoals ik al zei. Het haalt de lijst met de andere pizza-objecten op en herhaalt ze totdat het overeenkomt met de index. En twee bewerkingen om bij te werken! :( In deze situatie is het het beste om lijsten te vermijden.
Oplossing:
Aangezien u probeert toegang te krijgen tot de pizza via zijn ID, kunt u voor elk object een unieke pizzasleutel maken, zodat u rechtstreeks toegang hebt tot de pizza. Dus we kunnen gebruiken:
pizzas:live:{Id}
Voorbeelden:
Maak een 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);
}
Een pizza halen op 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);
}
Een pizza bijwerken op ID (Gewoon een GET en 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
}
Naar een andere "lijst" gaan (misschien:als een pizza van status verandert)
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);
}
Een pizza verwijderen
using (var redisClient = new RedisClient())
{
var pizzaKey = string.Format("pizzas:live:{0}", pizza.Id);
redisClient.Remove(pizzaKey);
}
Laat alle live pizza's zien
using (var redisClient = new RedisClient())
{
var livePizzaKeys = redisClient.ScanAllKeys("pizzas:live:*").ToList();
List<Pizza> livePizzas = redisClient.GetValues<Pizza>(livePizzaKeys);
}
Ik hoop dat dit helpt.