Hvis du bruger Stackechange.Redis, kan du bruge List-metoderne på dens API. Her er en naiv implementering af IList, der bruger en redis-liste til at gemme elementerne.
Forhåbentlig kan det hjælpe dig med at forstå nogle af listens API-metoder:
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());
}
}
}
Bemærk brugen af Newtonsoft.Json til serialiseringen. Du skal bruge følgende nu-get-pakker:
Install-Package Newtonsoft.Json
Install-Package StackExchange.Redis
Efter at have læst dit spørgsmål og dine kommentarer, da du ønsker at få adgang til elementer med nøgle, tror jeg, du leder efter Redis Hashes, som er kort sammensat af felter forbundet med værdier.
Så du kan have en Redis-nøgle til en Hash, der indeholder alle dine kunder, som hver især er en værdi knyttet til et felt. Du kan vælge CustomerId som feltet, så du derefter kan få en kunde efter dens id i O(1).
Jeg tror, at implementering af IDictionary er en god måde at se det fungere på. Så en RedisDictionary-klasse, der ligner RedisList, men ved at bruge en Redis Hash kunne være:
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());
}
}
Og her er nogle eksempler på at bruge det:
// 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];
Opdatering (okt 2015)
En bedre implementering af disse samlinger kan findes på CachingFramework.Redis-biblioteket.
Her er koden.