Jon*_*and 5 .net c# asp.net caching
我有一个基本的存储库框架,最终执行查询并将结果映射回对象:
例如:
public SomeEntity Get(id)
{
return base.GetItem<SomeEntity>
("select * from SomeEntities where id = @idParam",
new { idParam = id});
}
Run Code Online (Sandbox Code Playgroud)
如果这看起来像Dapper,那是因为引擎盖GetItem正在包装Dapper.
我想为GetItem添加自动缓存,我有两个参数:
我担心对这些参数执行简单的主要哈希会导致缓存密钥冲突,当您从缓存中提取数据时,冲突可能非常非常糟糕(IE泄漏敏感信息).
那么,我有哪些技术可以生成合理大小的缓存键,同时保证基于查询和参数输入的唯一性?
我使用以下扩展方法来创建委托的缓存版本:
public static Func<T, TResult> AsCached<T, TResult>(this Func<T, TResult> function)
{
var cachedResults = new Dictionary<T, TResult>();
return (argument) =>
{
TResult result;
lock (cachedResults)
{
if (!cachedResults.TryGetValue(argument, out result))
{
result = function(argument);
cachedResults.Add(argument, result);
}
}
return result;
};
}
public static Func<T1, T2, TResult> AsCached<T1, T2, TResult>(this Func<T1, T2, TResult> function)
{
var cachedResults = new Dictionary<Tuple<T1, T2>, TResult>();
return (value1, value2) =>
{
TResult result;
var paramsTuple = new Tuple<T1, T2>(value1, value2);
lock(cachedResults)
{
if (!cachedResults.TryGetValue(paramsTuple, out result))
{
result = function(value1, value2);
cachedResults.Add(paramsTuple, result);
}
}
return result;
};
}
public static Func<T1, T2, T3, TResult> AsCached<T1, T2, T3, TResult>(this Func<T1, T2, T3, TResult> function)
{
var cachedResults = new Dictionary<Tuple<T1, T2, T3>, TResult>();
return (value1, value2, value3) =>
{
TResult result;
var paramsTuple = new Tuple<T1, T2, T3>(value1, value2, value3);
lock(cachedResults)
{
if (!cachedResults.TryGetValue(paramsTuple, out result))
{
result = function(value1, value2, value3);
cachedResults.Add(paramsTuple, result);
}
}
return result;
};
}
Run Code Online (Sandbox Code Playgroud)
对N个参数等等......
如果从代码中不清楚,我使用参数创建一个元组,并使用元组作为字典的键,该字典包含每组参数的返回值.请注意,每次调用时AsCached,都会创建一个单独的缓存.
您可以使用以下方法:
private Func<int, SomeEntity> _getCached;
public SomeEntity Get(int id)
{
if (_getCached == null)
{
Func<int, SomeEntity> func = GetImpl;
_getCached = func.AsCached();
}
return _getCached(id);
}
private SomeEntity GetImpl(int id)
{
return base.GetItem<SomeEntity>
("select * from SomeEntities where id = @idParam",
new { idParam = id});
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4261 次 |
| 最近记录: |