“;信息”;适配器缓存
本文关键字:缓存 适配器 信息 | 更新日期: 2023-09-27 18:29:07
在Dapper的文档中,它指出:
限制和注意事项
Dapper缓存关于它运行的每个查询的信息 ,这使它能够快速实现对象并快速处理参数。当前实现将此信息缓存在ConcurrentDictionary对象中。
这到底意味着什么?例如:它是缓存返回的数据,还是缓存查询本身,或者缓存两者的比特?
它还说这个[缓存的]数据永远不会被刷新";。这是如何影响";缓存的信息";如果正在查询的表的设计模式发生了更改?
据我所知,根据sql查询、命令类型和参数,每个查询都会发出一个Identity
。缓存是一个具有并发访问功能的字典。
Dictionary<Identity, CacheInfo> _queryCache
这个CacheInfo
对象包含IDataReader
和IDBCommand
函数以及一些限制缓存量的控制计数器。
由于没有缓存服务器端(数据库模式等),所以它实际上没有任何影响。
编辑:这就是用于缓存的Identity类的样子。
private Identity(string sql, CommandType? commandType, string connectionString, Type type, Type parametersType, Type[] otherTypes, int gridIndex)
{
this.sql = sql;
this.commandType = commandType;
this.connectionString = connectionString;
this.type = type;
this.parametersType = parametersType;
this.gridIndex = gridIndex;
unchecked
{
hashCode = 17; // we *know* we are using this in a dictionary, so pre-compute this
hashCode = hashCode * 23 + commandType.GetHashCode();
hashCode = hashCode * 23 + gridIndex.GetHashCode();
hashCode = hashCode * 23 + (sql == null ? 0 : sql.GetHashCode());
hashCode = hashCode * 23 + (type == null ? 0 : type.GetHashCode());
if (otherTypes != null)
{
foreach (var t in otherTypes)
{
hashCode = hashCode * 23 + (t == null ? 0 : t.GetHashCode());
}
}
hashCode = hashCode * 23 + (connectionString == null ? 0 : connectionString.GetHashCode());
hashCode = hashCode * 23 + (parametersType == null ? 0 : parametersType.GetHashCode());
}
}
这是CacheInfo
class CacheInfo
{
public Func<IDataReader, object> Deserializer { get; set; }
public Func<IDataReader, object>[] OtherDeserializers { get; set; }
public Action<IDbCommand, object> ParamReader { get; set; }
private int hitCount;
public int GetHitCount() { return Interlocked.CompareExchange(ref hitCount, 0, 0); }
public void RecordHit() { Interlocked.Increment(ref hitCount); }
}
最后是缓存的容器。
static readonly System.Collections.Concurrent.ConcurrentDictionary<Identity, CacheInfo> _queryCache = new System.Collections.Concurrent.ConcurrentDictionary<Identity, CacheInfo>();
看一下源代码,它写得很好,很容易理解/调试。只需将文件拖动到项目中即可。
如果需要重置缓存,可以使用下一个代码
private static void ClearQueryCache()
{
var cacheDictionary = typeof(SqlMapper)
.GetField("_queryCache", BindingFlags.NonPublic | BindingFlags.Static)
.GetValue(null);
cacheDictionary.GetType()
.GetMethod("Clear", BindingFlags.Public | BindingFlags.Instance)
.Invoke(cacheDictionary, null);
}