2012-03-08 18 views
7

¿Hay alguna forma de restablecer el caché que genera Dapper? Bajé una columna de la tabla en mi base de datos, y recibí el error "columna no encontrada". Restablecé IIS y funcionó bien después de eso.Restaurar caché para Dapper

¿Se puede restablecer este valor sin reiniciar IIS? Gracias.

+0

Probablemente podamos * exponer * un método para esto; de hecho, tenemos algún código que se dirige específicamente a los cambios de esquema y está destinado a recuperarse silenciosamente; es extraño que no haya llegado a este código de recuperación. –

+0

@MarcGravell - ¿Los métodos de extensión que propuse en realidad hacen algo para resolver el problema? En el mejor de los casos, era una pobre suposición, pero sonaba bien cuando leía el código Dapper. –

+0

@ M.Babcock No lo he probado, pero parece que ayudaría –

Respuesta

7

actualización 2018-02-08

El código Dapper ha cambiado un poco desde esta respuesta fue escrito hace casi 5 años. Como Marc Gravell comentó sobre la pregunta, esto no debería haber sido necesario cuando se formuló la pregunta, por lo que probablemente tampoco sea de mucha utilidad hoy.

El código puede o no funcionar más. Incluso si todavía funciona, no es óptimo, así que no podría recomendarlo de buena fe. Úselo bajo su propio riesgo.


la línea 227 de Database.cs espectáculos:

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

que significa que es privada. Ni siquiera estoy seguro de que puedas acceder a él con Reflection (aunque valdría la pena intentarlo). Su mejor opción sería agregar un método ClearCache a la fuente (ya que es de código abierto) y enviarlo para su revisión.

Tal vez Sam Saffron o Marc Gravell puedan dar más detalles.


No consumo Dapper, pero creo que el siguiente método de extensión debe trabajar con la versión en 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); 
    } 
} 

No se ha probado con Dapper pero probado el principio usando POCO's El acceso a las API privadas es peligroso (en el mejor de los casos), pero la reflexión utilizada en este ejemplo de código debería funcionar con la versión actual.

+0

Actualizado para incluir un método de extensión que debería funcionar con la versión actual de Dapper. –

+0

Se agregó un método de extensión para borrar el caché de parámetros y se corrigieron ambos para que funcionen correctamente con el campo estático (se pasa por alto al principio). –