Tránh danh sách:
Thật không may, danh sách Redis không thực sự là một lựa chọn tốt trong tình huống này. Tôi đã gặp vấn đề tương tự khi bắt đầu sử dụng Redis, chúng có vẻ như là sự lựa chọn rõ ràng;). Danh sách Redis hữu ích nếu bạn đang sử dụng chúng dưới dạng tập hợp chỉ đọc hoặc nếu bạn chỉ muốn bật và đẩy, nhưng không phải để sửa đổi một mục ở giữa danh sách.
Bạn có thể "cập nhật" các mục trong danh sách Redis nếu bạn biết chỉ mục của mục đó, nhưng nó yêu cầu phải xóa và chèn lại , và nó phải theo chỉ số, việc xác định là không hiệu quả kinh khủng. Nó làm như vậy bằng cách lặp lại bộ sưu tập, bởi vì không có cách nào để làm điều đó và đây không phải là một ý tưởng hay. Đây là một đoạn mã của IndexOf
phương thức của 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;
}
Vì vậy, để hoàn thành mã của bạn, nó sẽ là:
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);
}
}
Nhưng đây không phải là một cách tốt để xử lý nó như tôi đã nói. Nó sẽ truy xuất danh sách các đối tượng pizza khác sau đó lặp lại chúng cho đến khi nó khớp với chỉ mục. Và hai thao tác để cập nhật! :( Tốt nhất nên tránh các danh sách trong trường hợp này.
Giải pháp:
Khi bạn đang cố gắng truy cập pizza bằng Id đó thì bạn có thể tạo một khóa pizza duy nhất cho từng đối tượng, điều này sẽ cho phép bạn truy cập trực tiếp vào pizza. Vì vậy, chúng tôi có thể sử dụng:
pizzas:live:{Id}
Ví dụ:
Tạo bánh 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);
}
Nhận một chiếc bánh pizza theo 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);
}
Cập nhật pizza theo Id (Đơn giản chỉ là NHẬN và ĐẶT)
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
}
Di chuyển sang "danh sách" khác (có thể:khi pizza thay đổi trạng thái)
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);
}
Xóa một chiếc bánh pizza
using (var redisClient = new RedisClient())
{
var pizzaKey = string.Format("pizzas:live:{0}", pizza.Id);
redisClient.Remove(pizzaKey);
}
Liệt kê tất cả các loại pizza sống
using (var redisClient = new RedisClient())
{
var livePizzaKeys = redisClient.ScanAllKeys("pizzas:live:*").ToList();
List<Pizza> livePizzas = redisClient.GetValues<Pizza>(livePizzaKeys);
}
Tôi hy vọng điều này sẽ hữu ích.