2012-03-08 50 views
7

有沒有方法可以重置Dapper生成的緩存?我在我的數據庫中刪除了一個表格列,並且出現錯誤「找不到列」。我重置IIS,並在此後正常工作。爲Dapper重置緩存

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

+0

然而,我們可能會*揭露*一種方法,我們實際上確實有一些專門針對模式更改的代碼,並且旨在以無提示的方式進行恢復 - 奇怪的是,它未打到此恢復代碼。 – 2012-03-11 20:07:12

+0

@MarcGravell - 我提出的擴展方法實際上是否可以解決問題?這是一個可憐的猜測,但我在閱讀Dapper代碼時聽起來不錯。 – 2012-03-11 21:50:06

+0

@ M.Babcock我還沒有測試過它,但它看起來會幫助 – 2012-03-12 07:44:48

回答

7

更新2018年2月8日

短小精悍代碼已經改變了不少,因爲這個答案几乎是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可以詳細說明。


我不使用小巧玲瓏,但我認爲下面的擴展方法應與版本回購工作:

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); 
    } 
} 

它尚未經過測試與精緻小巧,但我測試了以下原則:使用POCO的。訪問私有API是很危險的(最好),但是這個代碼示例中使用的反射應該與當前版本一起工作。

+0

更新以包含一個擴展方法,該擴展方法可以與當前版本的Dapper配合使用。 – 2012-03-08 03:40:18

+0

增加了擴展方法來清除參數緩存,並且修復了它們以正確使用靜態字段(首先忽略)。 – 2012-03-08 13:47:59