Réinitialiser le cache pour Dapper

asp.net-mvc c# dapper

Question

Existe-t-il un moyen de réinitialiser le cache généré par Dapper ? J'ai déposé une colonne de table dans ma base de données et j'ai eu l'erreur "colonne introuvable". Je réinitialise IIS et cela a bien fonctionné après cela.

Cela peut-il être réinitialisé sans redémarrer IIS? Merci.

Réponse populaire

Mise à jour 2018-02-08

Le code Dapper a beaucoup changé depuis que cette réponse a été écrite il y a presque 5 ans. Comme Marc Gravell a commenté la question, cela n'aurait pas dû être nécessaire lorsque la question a été posée, de sorte qu'elle ne serait probablement pas très utile aujourd'hui non plus.

Le code peut ou peut ne plus fonctionner. Même si cela fonctionne toujours, ce n'est pas optimal, alors je ne pourrais pas le recommander de bonne foi. À utiliser à vos risques et périls.


La ligne 227 de Database.cs montre:

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

ce qui signifie qu'il est privé. Je ne suis même pas sûr que vous puissiez y accéder avec Reflection (ça vaudrait cependant le coup). Votre meilleur pari serait d'ajouter une méthode ClearCache à la source (car elle est open source) et de l'envoyer pour révision.

Peut-être que Sam Saffron ou Marc Gravell peuvent élaborer.


Je n'utilise pas Dapper, mais je pense que la méthode d'extension suivante devrait fonctionner avec la version de Repo:

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);
    }
}

Il n'a pas été testé avec Dapper mais j'ai testé le principe à l'aide de POCO. L'accès aux API privées est dangereux (au mieux), mais la réflexion utilisée dans cet exemple de code devrait fonctionner avec la version actuelle.




Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi