感谢
Discosultan和
user1190916的帮助,他们引导我找到了使用Redis作为持久化存储(客户端
ServiceStack.Redis)的CRUD缓存对象仓库以及完整的LINQ支持所需的方向,这是我目前所能想出的。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Collections.Concurrent;
using ServiceStack.Redis;
namespace RedisTestRepo
{
class Program
{
static void Main(string[] args)
{
Repo r = new Repo();
Console.WriteLine("Our User Data store should be empty.");
Console.WriteLine("Users In \"Database\" : {0}\n", r.All<User>().Count);
Console.WriteLine("Adding 100 imaginairy users.");
for (int i = 0; i < 99; i++)
r.Create<User>(new User { Id = r.Next<User>(), Name = "Joachim Nordvik" });
Console.WriteLine("Users In \"Database\" : {0}\n", r.All<User>().Count);
Console.WriteLine("Order by Id, Take (10) and print users.");
foreach (var u in r.All<User>().OrderBy(z => z.Id).Take(10))
{
Console.WriteLine("ID:{0}, Name: {1}", u.Id, u.Name);
u.Name = "My new Name";
r.Update<User>(x=>x.Id == u.Id, u);
}
Console.WriteLine("\nOrder by Id, Take (20) and print users, we previously edited the users that we printed lets see if it worked.");
foreach (var u in r.All<User>().OrderBy(z => z.Id).Take(20))
{
Console.WriteLine("ID:{0}, Name: {1}", u.Id, u.Name);
}
Console.WriteLine("\nCleaning up Data Store.\n");
foreach (var u in r.All<User>())
r.Delete<User>(u);
Console.WriteLine("Confirm that we no longer have User entities in Data Store.");
Console.WriteLine("Users In \"Database\" : {0}\n\n", r.All<User>().Count);
Console.WriteLine("Hit return to exit!");
Console.Read();
}
}
public class Repo
{
private static readonly PooledRedisClientManager m = new PooledRedisClientManager();
public Repo()
{
LoadIntoCache<User>();
}
readonly IDictionary<Type, List<object>> _cache = new ConcurrentDictionary<Type, List<object>>();
private void LoadIntoCache<T>() where T : class
{
_cache[typeof(T)] = GetAll<T>().Cast<object>().ToList();
}
public void Create<T>(T entity) where T : class
{
List<object> list;
if (!_cache.TryGetValue(typeof(T), out list))
{
list = new List<object>();
}
list.Add(entity);
_cache[typeof(T)] = list;
Store<T>(entity);
}
public void Delete<T>(T entity) where T : class
{
List<object> list;
if (_cache.TryGetValue(typeof(T), out list))
{
list.Remove(entity);
_cache[typeof(T)] = list;
RedisDelete<T>(entity);
}
}
public void Update<T>(Func<T, bool> predicate, T entity) where T : class
{
List<object> list;
if (_cache.TryGetValue(typeof(T), out list))
{
var e = list.Cast<T>().Where(predicate).FirstOrDefault();
if(e != null)
{
list.Remove(e);
}
list.Add(entity);
_cache[typeof(T)] = list;
Store<T>(entity);
}
}
public List<T> FindBy<T>(Func<T, bool> predicate) where T : class
{
List<object> list;
if (_cache.TryGetValue(typeof(T), out list))
{
return list.Cast<T>().Where(predicate).ToList();
}
return new List<T>();
}
public List<T> All<T>() where T : class
{
return GetAll<T>().ToList();
}
public T Read<T>(Func<T, bool> predicate) where T : class
{
List<object> list;
if (_cache.TryGetValue(typeof(T), out list))
{
return list.Cast<T>().Where(predicate).FirstOrDefault();
}
return null;
}
public long Next<T>() where T : class
{
long id = 1;
using (var ctx = m.GetClient())
{
try
{
id = ctx.As<T>().GetNextSequence();
}
catch(Exception ex)
{
}
}
return id;
}
private void RedisDelete<T>(T entity) where T : class
{
using (var ctx = m.GetClient())
ctx.As<T>().Delete(entity);
}
private T Find<T>(long id) where T : class
{
using (var ctx = m.GetClient())
return ctx.As<T>().GetById(id);
}
private IList<T> GetAll<T>() where T : class
{
using(var ctx = m.GetClient())
{
try
{
return ctx.As<T>().GetAll();
}
catch
{
return new List<T>();
}
}
}
private void Store<T>(T entity) where T : class
{
using (var ctx = m.GetClient())
ctx.Store<T>(entity);
}
}
public class User
{
public long Id { get; set; }
public string Name { get; set; }
}
}
ConcurrentBag
上使用LINQ,并通过添加ToList()
来获取快照。 - Theodoros Chatzigiannakis