2012-03-08 2 views
7

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

Можно ли сбросить его без перезапуска IIS? Благодарю.

+0

Возможно, мы можем * разоблачить * метод для этого; у нас действительно есть некоторый код, который специально предназначен для изменений схемы и предназначен для восстановления молча - нечетно, что он не ударил этот код восстановления. –

+0

@MarcGravell - Будут ли предлагаемые методы расширения делать что-либо, чтобы решить проблему? В лучшем случае это было плохое предположение, но это звучало хорошо, когда я читал код Dapper. –

+0

@ M.Babcock Я не тестировал его, но похоже, что это помогло бы –

ответ

7

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

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

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


Line 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 к источнику (так как он открыт с открытым исходным кодом) и отправить его на рассмотрение.

Возможно, Сэм Шаффрон или Марк Гравелл могут разработать.


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

+0

Обновлено, чтобы включить метод расширения, который должен работать с текущей версией Dapper. –

+0

Добавлен метод расширения для очистки кеша параметров и исправлено оба из них для правильной работы со статическим полем (сначала игнорируется). –

Смежные вопросы