為Dapper重置緩存

asp.net-mvc c# dapper

有沒有辦法重置Dapper生成的緩存?我在我的數據庫中刪除了一個表列,我收到錯誤“未找到列”。我重置IIS,之後它工作正常。

可以在不重新啟動IIS的情況下重置嗎?謝謝。

熱門答案

更新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是危險的(充其量),但此代碼示例中使用的反射應該與當前版本一起使用。



許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因