如何在Redis缓存中存储列表元素

我已经将StackExchange.Redis用于c#redis缓存。

 cache.StringSet("Key1", CustomerObject); 

但我想存储数据

 cache.StringSet("Key1", ListOfCustomer); 

这样一个密钥就可以存储所有客户列表,并且很容易在该列表中搜索,分组,过滤客户数据

欢迎使用ServiceStack.RedisStackExchange.Redis

您可以使用ServiceStack.Redis高级IRedisTypedClient Typed API来管理丰富的POCO类型。

首先为客户获取一个类型化的Redis客户端:

 var redisCustomers = redis.As(); 

这将解析用于管理客户POCO的高级类型API,然后允许您通过以下方式持久保存单个客户:

 redisCustomers.SetEntry("Customer1", CustomerObject); 

或者客户列表:

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

如果使用Stackechange.Redis ,则可以在其API上使用List方法。 这是IList的一个简单实现,使用redis列表来存储项目。

希望它可以帮助您理解一些列表API方法:

 public class RedisList : IList { 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(string serialized) { return JsonConvert.DeserializeObject(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(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 GetEnumerator() { for (int i = 0; i < this.Count; i++) { yield return Deserialize(GetRedisDb().ListGetByIndex(key, i).ToString()); } } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { for (int i = 0; i < this.Count; i++) { yield return Deserialize(GetRedisDb().ListGetByIndex(key, i).ToString()); } } } 

请注意使用Newtonsoft.Json进行序列化。 您将需要以下nu-get包:

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

在阅读了您的问题和评论后,由于您希望按键访问元素,我认为您正在寻找Redis Hashes ,它是由与值相关联的字段组成的地图。

因此,您可以拥有包含所有客户的哈希的Redis密钥,每个客户都是与字段关联的值。 您可以选择CustomerId作为字段,这样您就可以通过其在O(1)中的ID获取客户。

我认为实现IDictionary是一种很好的方式来看它的工作原理。 所以类似于RedisList但使用Redis Hash的RedisDictionary类可以是:

 public class RedisDictionary : IDictionary { 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(string serialized) { return JsonConvert.DeserializeObject(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(redisValue.ToString()); return true; } public ICollection Values { get { return new Collection(GetRedisDb().HashValues(_redisKey).Select(h => Deserialize(h.ToString())).ToList()); } } public ICollection Keys { get { return new Collection(GetRedisDb().HashKeys(_redisKey).Select(h => Deserialize(h.ToString())).ToList()); } } public TValue this[TKey key] { get { var redisValue = GetRedisDb().HashGet(_redisKey, Serialize(key)); return redisValue.IsNull ? default(TValue) : Deserialize(redisValue.ToString()); } set { Add(key, value); } } public void Add(KeyValuePair item) { Add(item.Key, item.Value); } public void Clear() { GetRedisDb().KeyDelete(_redisKey); } public bool Contains(KeyValuePair item) { return GetRedisDb().HashExists(_redisKey, Serialize(item.Key)); } public void CopyTo(KeyValuePair[] 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 item) { return Remove(item.Key); } public IEnumerator> GetEnumerator() { var db = GetRedisDb(); foreach (var hashKey in db.HashKeys(_redisKey)) { var redisValue = db.HashGet(_redisKey, hashKey); yield return new KeyValuePair(Deserialize(hashKey.ToString()), Deserialize(redisValue.ToString())); } } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { yield return GetEnumerator(); } public void AddMultiple(IEnumerable> items) { GetRedisDb() .HashSet(_redisKey, items.Select(i => new HashEntry(Serialize(i.Key), Serialize(i.Value))).ToArray()); } } 

以下是一些使用它的示例:

 // Insert customers to the cache var customers = new RedisDictionary("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 customerListFromDb; customers.AddMultiple(customerListFromDb.ToDictionary(k => k.Id)); // Query a customer by its id var customers = new RedisDictionary("customers"); Customer customer100 = customers[100]; 

更新(2015年10月)

可以在CachingFramework.Redis库中找到这些集合的更好实现。

这是代码。

StackExchange.Redis已经预定义了处理列表和值集的函数。

获取IDatabase对象:

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

IDatabase cache = ConnectionMultiplexer.Connect(cacheConnection).GetDatabase();

列表方法:

cache.ListLeftPushAsync(key,values) – >推送一个元素列表

cache.ListRangeAsync(key,startIndex,endIndex) – >获取值列表

cache.KeyExpire(key,timspan)

请打包StackExchange.Redis以获取更多方法。 您不需要包含任何额外的nuget包。