Soweit ich weiß hat jede Abfrage Sie eine Identity
, abhängig von der SQL-Abfrage, seinen Befehlstyp und seine Parameter. Der Cache ist ein Wörterbuch mit gleichzeitigem Zugriff.
Dictionary<Identity, CacheInfo> _queryCache
Dieses CacheInfo
Objekt enthält die IDataReader
und IDBCommand
Funktionen und einige Steuerzähler, die die im Cache gespeicherte Menge begrenzen.
Da keine Server-Seite (Datenbankschema etc.) zwischengespeichert wird, hat sie eigentlich keinen Einfluss.
Edit: So sieht die Identity-Klasse aus, die zum Caching verwendet wird.
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());
}
}
Und hier ist der 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); }
}
Und schließlich der Behälter aus dem Cache.
static readonly System.Collections.Concurrent.ConcurrentDictionary<Identity, CacheInfo> _queryCache = new System.Collections.Concurrent.ConcurrentDictionary<Identity, CacheInfo>();
Werfen Sie einen Blick auf den Quellcode, es ist sehr gut geschrieben und einfach zu folgen/debuggen. Ziehen Sie die Datei einfach in Ihr Projekt.
Die Antwort auf meine zweite Frage scheint mir klarer zu sein als die Antwort auf die erste Frage. Was ich gewonnen habe ist, dass es die Abfragezeichenfolge speichert, aber keine Ergebnisse. Recht? Ich konnte nicht viel Dokumentation über die Identity oder CacheInfo finden. Irgendwelche guten Mittel, von denen Sie wissen, dass ich auf diesen lesen konnte? – JCisar
Ich nahm sie aus dem Quellcode. Lass mich die Info bekommen. – Alex
Danke! Genau das habe ich gesucht. – JCisar