Избягвайте списъци:
За съжаление списъците на Redis не са добър избор в тази ситуация. Имах същия проблем, когато започнах да използвам Redis, изглеждат като очевиден избор;). Redis списъците са полезни, ако ги използвате като набор само за четене или ако просто искате да изскочите и натиснете, но не и за промяна на елемент в средата на списъка.
Можете да „актуализирате“ елементи в списък Redis, ако знаете индекса на елемента, но това изисква премахване и вмъкнете отново , и трябва да е по индекс, което определянето е ужасно неефективно. Това става чрез повторение на колекцията, защото няма естествен начин да се направи това и това не е добра идея. Това е фрагмент от IndexOf
метод на 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;
}
Така че, за да завършите вашия код, той би бил:
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);
}
}
Но това не е добър начин да се справите, както казах. Той ще извлече списъка с другите обекти за пица, след което ще ги повтори, докато съвпадне с индекса. И две операции за актуализиране! :( Най-добре е да избягвате списъци в тази ситуация.
Решение:
Тъй като се опитвате да получите достъп до пицата по нейния идентификатор, тогава можете да създадете уникален ключ за пица за всеки обект, това ще ви позволи да получите директен достъп до пицата. Така че може да използваме:
pizzas:live:{Id}
Примери:
Създайте пица
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);
}
Вземете пица по идентификационен номер
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 и 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
}
Преместване към друг „списък“ (може би:когато пица промени състоянието си)
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);
}
Изтриване на пица
using (var redisClient = new RedisClient())
{
var pizzaKey = string.Format("pizzas:live:{0}", pizza.Id);
redisClient.Remove(pizzaKey);
}
Избройте всички пици на живо
using (var redisClient = new RedisClient())
{
var livePizzaKeys = redisClient.ScanAllKeys("pizzas:live:*").ToList();
List<Pizza> livePizzas = redisClient.GetValues<Pizza>(livePizzaKeys);
}
Надявам се това да помогне.