为Dapper重置缓存

时间:2012-03-08 02:42:11

标签: c# asp.net-mvc dapper

有没有办法重置Dapper生成的缓存?我在我的数据库中删除了一个表列,我收到错误“未找到列”。我重置了IIS,之后它运行良好。

可以在不重启IIS的情况下重置吗?感谢。

1 个答案:

答案 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是危险的(充其量),但此代码示例中使用的反射应该与当前版本一起使用。