it-swarm.com.de

Wie wird das Listenelement im Cache von Redis gespeichert?

Ich habe StackExchange.Redis für den Cache von c # redis verwendet.

cache.StringSet("Key1", CustomerObject);

aber ich möchte daten gerne speichern 

cache.StringSet("Key1", ListOfCustomer);

so dass ein Schlüssel alle Kundenlisten gespeichert hat und es einfach ist Suchen, Gruppieren, Filtern von Kundendaten auch in dieser Liste

Antworten sind willkommen mit ServiceStack.Redis oder StackExchange.Redis

14
Neo

Sie können ServiceStack.Redis High-Level IRedisTypedClient Typed API zum Verwalten von Rich-POCO-Typen verwenden. 

Zuerst erhalten Sie einen typisierten Redis-Client für Kunden mit:

var redisCustomers = redis.As<Customer>();

Dadurch wird eine typisierte API für die Verwaltung von Kunden-POCOs aufgelöst, mit der Sie einen einzelnen Kunden mit:

redisCustomers.SetEntry("Customer1", CustomerObject);

Oder eine Liste von Kunden mit:

redisCustomers.Lists["Customers"].AddRange(ListOfCustomer);
6
mythz

Wenn Sie Stackechange.Redis verwenden, können Sie die List-Methoden für ihre API verwenden. __ Hier ist eine naive Implementierung von IList, die die Elemente mit einer Redis-Liste speichert.

Hoffentlich hilft es Ihnen, einige der Listen-API-Methoden zu verstehen:

public class RedisList<T> : IList<T>
{
    private static ConnectionMultiplexer _cnn;
    private string key;
    public RedisList(string key)
    {
        this.key = key;
        _cnn = ConnectionMultiplexer.Connect("localhost");
    }
    private IDatabase GetRedisDb()
    {
        return _cnn.GetDatabase();
    }
    private string Serialize(object obj)
    {
        return JsonConvert.SerializeObject(obj);
    }
    private T Deserialize<T>(string serialized)
    {
        return JsonConvert.DeserializeObject<T>(serialized);
    }
    public void Insert(int index, T item)
    {
        var db = GetRedisDb();
        var before = db.ListGetByIndex(key, index);
        db.ListInsertBefore(key, before, Serialize(item));
    }
    public void RemoveAt(int index)
    {
        var db = GetRedisDb();
        var value = db.ListGetByIndex(key, index);
        if (!value.IsNull)
        {
            db.ListRemove(key, value);
        }
    }
    public T this[int index]
    {
        get
        {
            var value = GetRedisDb().ListGetByIndex(key, index);
            return Deserialize<T>(value.ToString());
        }
        set
        {
            Insert(index, value);
        }
    }
    public void Add(T item)
    {
        GetRedisDb().ListRightPush(key, Serialize(item));
    }
    public void Clear()
    {
        GetRedisDb().KeyDelete(key);
    }
    public bool Contains(T item)
    {
        for (int i = 0; i < Count; i++)
        {
            if (GetRedisDb().ListGetByIndex(key, i).ToString().Equals(Serialize(item)))
            {
                return true;
            }
        }
        return false;
    }
    public void CopyTo(T[] array, int arrayIndex)
    {
        GetRedisDb().ListRange(key).CopyTo(array, arrayIndex);
    }
    public int IndexOf(T item)
    {
        for (int i = 0; i < Count; i++)
        {
            if (GetRedisDb().ListGetByIndex(key, i).ToString().Equals(Serialize(item)))
            {
                return i;
            }
        }
        return -1;
    }
    public int Count
    {
        get { return (int)GetRedisDb().ListLength(key); }
    }
    public bool IsReadOnly
    {
        get { return false; }
    }
    public bool Remove(T item)
    {
        return GetRedisDb().ListRemove(key, Serialize(item)) > 0;
    }
    public IEnumerator<T> GetEnumerator()
    {
        for (int i = 0; i < this.Count; i++)
        {
            yield return Deserialize<T>(GetRedisDb().ListGetByIndex(key, i).ToString());
        }
    }
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        for (int i = 0; i < this.Count; i++)
        {
            yield return Deserialize<T>(GetRedisDb().ListGetByIndex(key, i).ToString());
        }
    }
}

Beachten Sie die Verwendung von Newtonsoft.Json für die Serialisierung. Sie benötigen die folgenden nu-get-Pakete:

Install-Package Newtonsoft.Json
Install-Package StackExchange.Redis

Nachdem Sie Ihre Fragen und Kommentare gelesen haben, möchten Sie, da Sie auf Schlüsselelemente zugreifen möchten, nach Redis Hashes suchen. Hierbei handelt es sich um Karten, die aus Feldern bestehen, die mit Werten verknüpft sind.

Sie können also einen Redis-Schlüssel für einen Hash verwenden, der alle Ihre Kunden enthält, wobei jeder Wert ein mit einem Feld verknüpfter Wert ist. Sie können die CustomerId als Feld auswählen, um dann einen Kunden anhand seiner ID in O (1) zu erhalten.

Ich denke, die Implementierung von IDictionary ist ein guter Weg, um zu sehen, wie es funktioniert. Eine RedisDictionary-Klasse, die der RedisList ähnelt, aber einen Redis-Hash verwenden könnte, könnte Folgendes sein:

public class RedisDictionary<TKey, TValue> : IDictionary<TKey, TValue>
{
    private static ConnectionMultiplexer _cnn;
    private string _redisKey;
    public RedisDictionary(string redisKey)
    {
        _redisKey = redisKey;
        _cnn = ConnectionMultiplexer.Connect("localhost");
    }
    private IDatabase GetRedisDb()
    {
        return _cnn.GetDatabase();
    }
    private string Serialize(object obj)
    {
        return JsonConvert.SerializeObject(obj);
    }
    private T Deserialize<T>(string serialized)
    {
        return JsonConvert.DeserializeObject<T>(serialized);
    }
    public void Add(TKey key, TValue value)
    {
        GetRedisDb().HashSet(_redisKey, Serialize(key), Serialize(value));
    }
    public bool ContainsKey(TKey key)
    {
        return GetRedisDb().HashExists(_redisKey, Serialize(key));
    }
    public bool Remove(TKey key)
    {
        return GetRedisDb().HashDelete(_redisKey, Serialize(key));
    }
    public bool TryGetValue(TKey key, out TValue value)
    {
        var redisValue = GetRedisDb().HashGet(_redisKey, Serialize(key));
        if (redisValue.IsNull)
        {
            value = default(TValue);
            return false;
        }
        value = Deserialize<TValue>(redisValue.ToString());
        return true;
    }
    public ICollection<TValue> Values
    {
        get { return new Collection<TValue>(GetRedisDb().HashValues(_redisKey).Select(h => Deserialize<TValue>(h.ToString())).ToList()); }
    }
    public ICollection<TKey> Keys
    {
        get { return new Collection<TKey>(GetRedisDb().HashKeys(_redisKey).Select(h => Deserialize<TKey>(h.ToString())).ToList()); }
    }
    public TValue this[TKey key]
    {
        get
        {
            var redisValue = GetRedisDb().HashGet(_redisKey, Serialize(key));
            return redisValue.IsNull ? default(TValue) : Deserialize<TValue>(redisValue.ToString());
        }
        set
        {
            Add(key, value);
        }
    }
    public void Add(KeyValuePair<TKey, TValue> item)
    {
        Add(item.Key, item.Value);
    }
    public void Clear()
    {
        GetRedisDb().KeyDelete(_redisKey);
    }
    public bool Contains(KeyValuePair<TKey, TValue> item)
    {
        return GetRedisDb().HashExists(_redisKey, Serialize(item.Key));
    }
    public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
    {
        GetRedisDb().HashGetAll(_redisKey).CopyTo(array, arrayIndex);
    }
    public int Count
    {
        get { return (int)GetRedisDb().HashLength(_redisKey); }
    }
    public bool IsReadOnly
    {
        get { return false; }
    }
    public bool Remove(KeyValuePair<TKey, TValue> item)
    {
        return Remove(item.Key);
    }
    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
    {
        var db = GetRedisDb();
        foreach (var hashKey in db.HashKeys(_redisKey))
        {
            var redisValue = db.HashGet(_redisKey, hashKey);
            yield return new KeyValuePair<TKey, TValue>(Deserialize<TKey>(hashKey.ToString()), Deserialize<TValue>(redisValue.ToString()));
        }
    }
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        yield return GetEnumerator();
    }
    public void AddMultiple(IEnumerable<KeyValuePair<TKey, TValue>> items)
    {
        GetRedisDb()
            .HashSet(_redisKey, items.Select(i => new HashEntry(Serialize(i.Key), Serialize(i.Value))).ToArray());
    }
}

Und hier sind einige Beispiele, um es zu benutzen:

// Insert customers to the cache            
var customers = new RedisDictionary<int, Customer>("customers");
customers.Add(100, new Customer() { Id = 100, Name = "John" });
customers.Add(200, new Customer() { Id = 200, Name = "Peter" });

// Or if you have a list of customers retrieved from DB:
IList<Customer> customerListFromDb;
customers.AddMultiple(customerListFromDb.ToDictionary(k => k.Id));

// Query a customer by its id
var customers = new RedisDictionary<int, Customer>("customers");
Customer customer100 = customers[100];

Update (Okt 2015)

Eine bessere Implementierung dieser Sammlungen finden Sie in der Bibliothek CachingFramework.Redis .

Hier ist der Code.

26
thepirat000

StackExchange.Redis verfügt bereits über vordefinierte Funktionen zum Umgang mit Listen und Werten.

IDatabase-Objekt abrufen:

string cacheConnection = Utils.Sections.Storage.RedisCache.ConnectionString;

IDatabase-Cache = ConnectionMultiplexer.Connect (cacheConnection) .GetDatabase ();

Methoden der Liste:  

cache.ListLeftPushAsync (Schlüssel, Werte) -> Schieben Sie eines der Elemente in die Liste

cache.ListRangeAsync (key, startIndex, endIndex) -> Liste der Werte abrufen

cache.KeyExpire (Schlüssel, Zeitspanne)

bitte packen Sie StackExchange.Redis für weitere Methoden. Sie müssen kein zusätzliches Nuget-Paket hinzufügen.

0
Happy Mittal