更新服务栈Redis的列表 [英] Updating Service Stack Redis List
问题描述
是否有更新IRedisList一个正确的方法是什么?下面的示例代码,我可以修改它来删除列表,更新比萨饼和重新添加列表,但那种感觉是错误的。命令行的文件是非常thourough,但它是一个更大的项目比我,虽然我不完全知道从哪里开始寻找。
公共无效UpdatePizza(比萨比萨)
{
使用(VAR redisClient =新RedisClient(主机,端口))
{
IRedisTypedClient<披萨> Redis的= redisClient.As<披萨>();
IRedisList<披萨>比萨饼= redis.Lists [比萨饼:活];
变种更新所使用= pizzas.First(X => x.Id == pizza.Id);
toUpdate.State = pizza.State;
// ??如何节省
}
}
避免列表:
不幸的是Redis的名单不是一个真正的好选择在这STRONG>情况。我有同样的问题,当我开始使用Redis的,的他们似乎显而易见的选择)。 Redis的列表是有用的,如果你正在使用他们作为只读集,或者如果你只是想弹出和推动,而不是在列表的中间修改的项目。的
您可以在一个Redis的名单更新的项目,如果你知道该项目的索引,但它需要的删除的和的重新插入的,并它必须通过索引,其中,确定是可怕的效率低下。它这样做是通过遍历collection,因为这样做没有本土的方式,这是不是一个好主意。 这是<$的一个片段 C $ C>的IndexOf 的 RedisClientList<的方法; T>
公众诠释的IndexOf(T项目)
{
// TODO:替换本机实现时存在
变种i = 0;
的foreach(在此VAR existingItem)
{
如果(等于(existingItem,项目))回报我;
I ++;
}
返回-1;
}
因此,要完成你的代码,这将是:
<预类=郎-CS prettyprint-覆盖>
公共无效UpdatePizza(比萨比萨)
{
使用(VAR redisClient =新redisClient(主机港))
{
IRedisTypedClient<披萨> Redis的= redisClient.As<披萨>();
IRedisList<披萨>比萨饼= redis.Lists [比萨饼:活];
变种更新所使用= pizzas.First(X => x.Id == pizza.Id);
toUpdate.State = pizza.State;
//更新通过删除和放大器;插入(不这样做!)
VAR指数= pizzas.IndexOf(更新所使用);
pizzas.Remove(指数);
pizzas.Insert(索引,更新所使用);
}
}
但是,这不是来处理它一个很好的方式正如我刚才所说。它将检索其他比萨饼对象列表然后经迭代它们,直到它的索引相匹配。和两个操作来更新! 。:(最好避免在这种情况下,列出了
解决方案:
当你试图访问披萨通过它的ID,那么你可以为每个对象的唯一比萨饼关键,这将允许您直接访问比萨所以我们可以使用:
比萨饼:现场:{ID}
的例子:
创建比萨饼
<预类=郎-CS prettyprint-覆盖>
使用( VAR redisClient =新RedisClient())
{
IRedisTypedClient<披萨>的Redis = redisClient.As<披萨>();
VAR pizzaKey =的String.Format(比萨饼:现场:{0 },123);
变种比萨饼=新的比萨饼{ID = 123,类型=蘑菇,国家=烹饪};
redis.SetEntry(pizzaKey,比萨饼);
}
由id来获取一个比萨饼
<预类=郎-CS prettyprint-覆盖>
使用(VAR redisClient =新redisClient())
{
IRedisTypedClient<披萨> Redis的= redisClient.As<披萨>();
VAR pizzaKey =的String.Format(比萨饼:住:{0},pizza.Id);
VAR比萨饼= redis.GetValue(pizzaKey);
}
更新通过ID的比萨饼(只是一个GET和SET)
<预类=郎-CS prettyprint-覆盖>
使用(VAR redisClient =新redisClient())
{
IRedisTypedClient<披萨> Redis的= redisClient.As<披萨>();
VAR pizzaKey =的String.Format(比萨饼:住:{0},pizza.Id);
VAR比萨饼= redis.GetValue(pizzaKey); //获取
pizza.State =交货; //更新
redis.SetEntry(pizzaKey,比萨饼); //保存
}
移动到另一个清单 (可能:当比萨饼改变状态)
<预类=郎-CS prettyprint-覆盖>使用
(VAR redisClient =新redisClient())
{
VAR pizzaKey =的String.Format(比萨饼:现场:{0},pizza.Id);
VAR deliveredKey =的String.Format(比萨饼:交付:{0},pizza.Id);
redisClient.RenameKey(pizzaKey,deliveredKey);
}
删除比萨饼
<预类=郎-CS prettyprint-覆盖>
使用(VAR redisClient =新RedisClient())
{
VAR pizzaKey =的String.format (比萨饼:住:{0},pizza.Id);
redisClient.Remove(pizzaKey);
}
列出所有活比萨饼
<预类=郎-CS prettyprint-覆盖>
使用(VAR redisClient =新RedisClient())
{
VAR livePizzaKeys = redisClient .ScanAllKeys(比萨饼:直播:*)了ToList();
名单,LT;披萨> livePizzas = redisClient.GetValues<披萨>(livePizzaKeys);
}
我希望这有助于。
Is there a correct way to update a IRedisList? With the sample code below, I can modify it to remove the list, update the pizza and the re-add the list, but that feels wrong. The command line documentation is pretty thourough, but it's a much bigger project than I though and I'm not entirely sure where to start looking.
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;
//??How to save
}
}
Avoid Lists:
Unfortunately Redis lists are not really a good choice in this situation. I had the same issue when I started using Redis, they seem like the obvious choice ;). Redis lists are useful if you are using them as a readonly set, or if you just want to pop and push, but not for modifying an item in the middle of the list.
You can "update" items in a Redis list if you know the index of the item, but it requires to remove and re-insert, and it must be by index, which determining is horribly inefficient. It does so by iterating the collection, because there is no native way to do it, and this isn't a good idea. This is a snippet of the IndexOf
method of the 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;
}
So to complete your code, it would be:
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);
}
}
But this isn't a nice way to handle it as I have said. It will retrieve the list of the other pizza objects then iterate over them until it matches the index. And two operations to update! :( Best to avoid lists in this situation.
Solution:
As you are trying to access the pizza by it's Id then you can create a unique pizza key for each object, this will allow you to access the pizza directly. So we might use:
pizzas:live:{Id}
Examples:
Create a 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);
}
Get a pizza by 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);
}
Update a pizza by Id (Simply a GET and 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
}
Move to another "list" (maybe: when a pizza changes state)
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);
}
Delete a pizza
using (var redisClient = new RedisClient())
{
var pizzaKey = string.Format("pizzas:live:{0}", pizza.Id);
redisClient.Remove(pizzaKey);
}
List all the live pizzas
using (var redisClient = new RedisClient())
{
var livePizzaKeys = redisClient.ScanAllKeys("pizzas:live:*").ToList();
List<Pizza> livePizzas = redisClient.GetValues<Pizza>(livePizzaKeys);
}
I hope this helps.
这篇关于更新服务栈Redis的列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!