2011-02-03 23 views
3

我正在嘗試構建通用緩存層。 ICacheRepository從Func提取信息<bool, T>或類似的lambda

說我有以下幾點:

public class Person 
{ 
    public int PersonId { get; set; } 
    public string Firstname { get; set; } 
    public string Lastname { get; set; } 
    public DateTime Added { get; set; } 
} 

而且我有這樣的事情:

list.Where(x => x.Firstname == "Syska"); 

在這裏,我想提取上述信息,看是否查詢提供的「PERSONID 「它沒有,所以我不想緩存它。

但可以說我像這樣運行的查詢:

list.Where(x => x.PersonId == 10); 

由於PERSONID是我的鑰匙......我想緩存它。用「Person_10」這樣的關鍵字,我稍後可以從緩存中獲取它。

我知道它可以提取與Expression<Func<>>信息,但似乎有這樣做(運行編譯和提取恆值等和一堆緩存就一定要正確分析時)

的一筆大開銷

有沒有這樣的框架?或者做一些聰明/黃金的方式?

更新的信息:

我使用EF代碼第一次CTP5。

當通過我的存儲庫訪問實體並僅查詢數據類的某些特定屬性時,我想將其保存到緩存。

所以在做的時候:

repository.SingleOrDefault(x => x.Email == "[email protected]"); 

並通過電子郵件發送是「用戶」實體我的緩存鍵,我想我的倉庫緩存它,因爲它是由「電子郵件」查詢。

Expression<Func<User, bool>> b; 
b.Body // Here I can extract most information without compiling it, to fetch what its being quried for. 

它不是說我不能創建一個表達式解析器,但正如你說,有很多優勢的情況下,在現有的SQL提供商的方式更好。但那不是我想在這裏做的。

我簡單的想提取BinaryExpression ....右邊的最好和最快的方法。由於編譯每個查詢都很慢。

更好的是我只想爲EF Code First創建一個緩存層。

回答

3

爲了做到這一點,你實際上想要處理Expression<Func<bool, T>>。這包含必要的元數據(以表達式對象的形式),以允許您檢查查詢中實際指定的內容。這就是LINQ到SQL和實體框架這樣的ORM如何執行從強類型查詢表達式到其各自查詢層(LINQ到SQL直接到SQL,實體框架到實體SQL等)的轉換。

有兩種方法可以獲取此信息。

  1. 實施IQueryable<T>。這是所有LINQ提供者(如上面列出的)實現的標準查詢界面。
  2. 在你的類型上聲明一個名爲Where的函數,該函數以Expression<Func<bool, T>>作爲它的參數。

無論哪種方式,你會得到的表達。然後你可以做任何你喜歡的事情,包括編譯它並作爲普通代碼執行它。

如果您想開始使用,請轉至MSDN並查看。有很多信息,但它應該能夠回答您的任何問題。如果沒有,你已經知道如何在這裏問一個問題!

+0

感謝ansvar。我知道ORM是這樣做的。我也讀了它的一項艱鉅的工作來完成它,因此它產生乾淨和漂亮的SQL。我希望有一些庫/框架可以幫助我實現這個目標。 – Syska 2011-02-04 00:41:54

0

定義自己的擴展方法Person GetById(this List<Person> list, int personId)可能更可取。只要程序員記得調用特殊的方法,緩存纔會有效,但它會表現得更好。

相關問題