更新服务栈Redis的列表 [英] Updating Service Stack Redis List

查看:263
本文介绍了更新服务栈Redis的列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有更新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的名单不是一个真正的好选择情况。我有同样的问题,当我开始使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆