Сброс кеша для Dapper - PullRequest
7 голосов
/ 08 марта 2012

Есть ли способ сбросить кэш, который генерирует Dapper ? Я удалил столбец таблицы в своей базе данных и получил ошибку «Столбец не найден». Я сбросил IIS, и после этого он работал нормально.

Может ли это быть сброшено без перезапуска IIS? Спасибо.

1 Ответ

8 голосов
/ 08 марта 2012

Обновление 2018-02-08

Код Dapper сильно изменился с тех пор, как этот ответ был написан почти 5 лет назад.Как прокомментировал вопрос Марк Гравелл, это не должно было понадобиться, когда вопрос был задан, поэтому, вероятно, сегодня оно тоже не будет иметь большого значения.

Код может работать, а может и не работать.Даже если это все еще работает, это не оптимально, поэтому я не могу рекомендовать это добросовестно.Используйте на свой страх и риск.


Строка 227 из Database.cs показывает:

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

, что означает, что это личное.Я даже не уверен, что вы сможете получить к нему доступ с помощью Reflection (хотя это того стоит).Лучше всего было бы добавить метод ClearCache к источнику (поскольку он является открытым исходным кодом) и представить его на рассмотрение.

Может быть, Сэм Саффрон или Марк Гравелл могут уточнить.1020 * Я не использую Dapper, но я думаю, что следующий метод расширения должен работать с версией в 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);
    }
}

Он не был протестирован с Dapper, но я проверил принцип, используя POCO.Доступ к частным API опасен (в лучшем случае), но отражение, используемое в этом примере кода, должно работать с текущей версией.

...