Cache für Dapper zurücksetzen

asp.net-mvc c# dapper

Frage

Gibt es eine Möglichkeit, den von Dapper generierten Cache zurückzusetzen? Ich habe eine Tabellenspalte in meiner Datenbank gelöscht und den Fehler "Spalte nicht gefunden" erhalten. Ich habe IIS zurückgesetzt und es funktionierte danach gut.

Kann dies zurückgesetzt werden, ohne IIS neu zu starten? Vielen Dank.

Beliebte Antwort

Update 2018-02-08

Der Dapper-Code hat sich ziemlich verändert, seit diese Antwort vor fast 5 Jahren geschrieben wurde. Wie Marc Gravell zu der Frage sagte, hätte dies bei der Beantwortung der Frage nicht erforderlich sein sollen, so dass es auch heute wahrscheinlich nicht viel nutzen würde.

Der Code funktioniert möglicherweise nicht mehr. Auch wenn es noch funktioniert, ist es nicht optimal und ich kann es nicht in gutem Glauben empfehlen. Benutzung auf eigene Gefahr.


Zeile 227 von Database.cs zeigt:

static ConcurrentDictionary<Type, string> tableNameMap = new ConcurrentDictionary<Type, string>();
static ConcurrentDictionary<Type, List<string>> paramNameCache = new ConcurrentDictionary<Type, List<string>>();

was bedeutet, dass es privat ist. Ich bin mir nicht einmal sicher, ob du mit Reflection darauf zugreifen könntest (es wäre aber einen Versuch wert). Am besten wäre es, der Quelle eine ClearCache Methode hinzuzufügen (da sie Open Source ist) und sie zur Überprüfung einzureichen.

Vielleicht können Sam Saffron oder Marc Gravell etwas ausarbeiten.


Ich verwende Dapper nicht, aber ich denke, die folgende Erweiterungsmethode sollte mit der Version in Repo funktionieren:

public static class DapperExtensions
{
    public static void ClearTableCache<TDatabase>(this Database<TDatabase> dapperDb)
    {
        var fld = dapperDb.GetType().GetField("tableNameMap", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
        if (fld == null)
            throw new NotSupportedException("Unable to locate Private field tableNameMap");

        var obj = fld.GetValue(null);
        if (obj == null)
            throw new NotSupportedException("Unable to get value from tableNameMap");

        var clear = obj.GetType().GetMethod("Clear");
        if (clear == null)
            throw new NotSupportedException("Unable to locate ConcurrentDictionary<T, U>.Clear");

        clear.Invoke(obj, null);
    }
    public static void ClearParamCache<TDatabase>(this Database<TDatabase> dapperDb)
    {
        var fld = dapperDb.GetType().GetField("paramNameCache", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
        if (fld == null)
            throw new NotSupportedException("Unable to locate Private field paramNameMap");

        var obj = fld.GetValue(null);
        if (obj == null)
            throw new NotSupportedException("Unable to get value from paramNameMap");

        var clear = obj.GetType().GetMethod("Clear");
        if (clear == null)
            throw new NotSupportedException("Unable to locate ConcurrentDictionary<T, U>.Clear");

        clear.Invoke(obj, null);
    }
}

Es wurde nicht mit Dapper getestet, aber ich habe das Prinzip mit POCO's getestet. Der Zugriff auf private APIs ist (im besten Fall) gefährlich, aber die in diesem Codebeispiel verwendete Reflektion sollte mit der aktuellen Version funktionieren.



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum