我在带有Entity Framework 6项目的ASP.NET MVC 5中使用EFCache.Redis库来缓存查询结果。这个包的test project中有一些很好的例子:
[TestMethod]
public void Item_cached()
{
var cache = new RedisCache("localhost:6379");
var item = new TestObject { Message = "OK" };
cache.PutItem("key", item, new string[0], TimeSpan.MaxValue, DateTimeOffset.MaxValue);
object fromCache;
Assert.IsTrue(cache.GetItem("key", out fromCache));
Assert.AreEqual(item.Message, ((TestObject)fromCache).Message);
Assert.IsTrue(cache.GetItem("key", out fromCache));
Assert.AreEqual(item.Message, ((TestObject)fromCache).Message);
}
但我需要的是像助手类一样避免重复代码。所以我写了这段代码:
public class CacheManager : ICacheManager
{
private RedisCache _cache;
public CacheManager()
{
_cache = new RedisCache("localhost:6379");
}
public object GetCache(string key, Func<object> factory, string[] relatedEntitties = null)
{
if (string.IsNullOrEmpty(key))
throw new Exception("Cache key cannot be null");
if (relatedEntitties == null)
relatedEntitties = new string[0];
object fromCache;
_cache.GetItem(key, out fromCache);
if (fromCache == null)
{
fromCache = factory();
_cache.PutItem(key, fromCache, relatedEntitties, TimeSpan.MaxValue, DateTimeOffset.MaxValue);
}
return fromCache;
}
public void InvalidateCache(string key)
{
_cache.InvalidateItem(key);
}
public void InvalidateSets(string[] sets)
{
_cache.InvalidateSets(sets);
}
}
并像这样使用它:
CacheManager cacheManager = new CacheManager();
var artists = cacheManager.GetCache("artists", () => getArtists(), new string[] { "Artist" });
“getArtists”方法:
private List<Artist> getArtists()
{
var artists = new List<Artist>();
using (var ctx = new MusicStoreContext())
{
artists = ctx.Artists.ToList();
}
return artists;
}
在“GetCache”方法中,我检查实体是否存在于缓存中,我使用它,否则从数据库中查询。这部分没有问题,但是我不确定的是连接到我在类构造函数中实现的redis服务器。通过这种方式,我创建了一个CacheManager实例,它尝试连接到服务器。我不知道是真的吗?或者它应该连接一次?我可以将此类设置为静态吗?一般来说,如果有人知道更好的方法,我想知道帮助类的最佳实现。