我有两个类似的问题:
ICmOption optionRes = CmOptionRepository<ICmOption>
.GetAll()
.Where(option => option.Name == strCommandName && option.Data == strCommandOption)
.FirstOrDefault()
;
IErrorType errorType = ErrorTypeRepository<IErrorType>
.GetAll()
.Where(et => et.ComponentId == (int)component.Id && et.ComponentErrorCode == strErrorCode)
.First()
;
在这两种情况下,都会获取来自DB的常量数据。由于这个原因,我想缓存这些查询的结果......
一个请求的最简单的解决方案是:
public IErrorType GetErrorType(IComponent component, string strErrorCode)
{
IErrorType errorType;
string strKey = string.Concat(component.Id, "_", strErrorCode);
lock (Dict)
{
if (Dict.ContainsKey(strKey))
{
errorType = Dict[strKey];
}
else
{
errorType = Repository
.GetAll()
.Where(et => et.ComponentId == (int)component.Id && et.ComponentErrorCode == strErrorCode)
.First()
;
Dict.Add(strKey, errorType);
}
}
return errorType;
}
private static Dictionary<string, IErrorType> Dict { get { return _dict; } }
private static readonly Dictionary<string, IErrorType> _dict
= new Dictionary<string, IErrorType>();
我确实需要第二个实体的相似内容,而且还有更多内容......所以我想创建一个接受参数的类(CachableRepository),检查它们的对象是否已经缓存,如果没有 - 获取数据从DB并放入缓存。这应该适用于不同数量的参数..
问题是:我没有看到如何为不同参数创建缓存密钥的简单方法,以及如何为这些参数构建lambda函数...
如果您有任何想法或建议,请分享。
非常感谢!
答案 0 :(得分:1)
我自己的'快速'解决方案:
internal class CacheManager<TIEntity>
where TIEntity : IEntity
{
internal TIEntity GetObject(string strKey, Func<TIEntity> funcGetEntity)
{
TIEntity entity;
lock (Dict)
{
if (Dict.ContainsKey(strKey))
{
entity = Dict[strKey];
}
else
{
entity = funcGetEntity();
Dict.Add(strKey, entity);
}
}
return entity;
}
private Dictionary<string, TIEntity> Dict { [DebuggerStepThrough] get { return _dict; } }
private readonly Dictionary<string, TIEntity> _dict = new Dictionary<string, TIEntity>();
}
public IErrorType GetErrorType(IComponent component, string strErrorCode)
{
string strKey = string.Concat(component.Id, "_", strErrorCode);
IErrorType errorType = _sCacheManager.GetObject(
strKey,
() => Repository
.GetAll()
.Where(et => et.ComponentId == (int)component.Id && et.ComponentErrorCode == strErrorCode)
.First()
);
return errorType;
}
private static CacheManager<IErrorType> _sCacheManager = new CacheManager<IErrorType>();
如果您看到更好的选择,请告诉我。
非常感谢!
答案 1 :(得分:1)
我几乎到处都使用这个方法来处理ASP.NET缓存中的缓存对象,可以修改它来缓存在Dictionary中。
public static T GetOrInsert<T>(string cacheKey, Func<T> creator)
{
object cacheItem = HttpRuntime.Cache.Get(cacheKey);
if (cacheItem is T)
{
return (T)cacheItem;
}
else
{
T newItem = creator();
HttpRuntime.Cache.Insert(cacheKey, newItem);
return newItem;
}
}
然后您可以像
一样使用它public IErrorType GetErrorType(IComponent component, string strErrorCode)
{
string strKey = string.Concat(component.Id, "_", strErrorCode);
return CacheUtil.GetOrInsert<IErrorType>( strKey,
() => Repository
.GetAll()
.Where(et => et.ComponentId == (int)component.Id && et.ComponentErrorCode == strErrorCode)
.First()
);
}