有没有办法重置Dapper生成的缓存?我在我的数据库中删除了一个表列,我收到错误“未找到列”。我重置了IIS,之后它运行良好。
可以在不重启IIS的情况下重置吗?感谢。
答案 0 :(得分:8)
更新2018-02-08
Dapper代码已经发生了很大的变化,因为这个答案大约写在5年前。正如马克·格拉维尔(Marc Gravell)对这个问题发表评论的那样,当问到这个问题时就不应该这样做,所以它今天可能也没什么用处。
代码可能会或可能不会再起作用。即使它仍然有效,但它并不是最佳的,所以我不能真诚地推荐它。使用风险自负。
Database.cs的第227行显示:
static ConcurrentDictionary<Type, string> tableNameMap = new ConcurrentDictionary<Type, string>();
static ConcurrentDictionary<Type, List<string>> paramNameCache = new ConcurrentDictionary<Type, List<string>>();
这意味着它是私人的。我甚至不确定你能用反射来访问它(虽然它值得一试)。您最好的选择是向源添加ClearCache
方法(因为它是开源的)并提交以供审核。
也许Sam Saffron或Marc Gravell可以详细说明。
我不使用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是危险的(充其量),但此代码示例中使用的反射应该与当前版本一起使用。