[Expression Tree] LINQ動態欄位查詢-動態代理類別

  在前一篇文章"LINQ動態欄位查詢"介紹到使用Expression來作欄位的動態查詢,但此方法有一缺點是因EntityFramework在查詢時,不能回傳與來源型別一樣的結果,所以使用上會變成查ProductEntity但回傳另一型別ProductInfo。若只是基本的單資料表查詢,那倒還好,但在實務上通常會Join到其他資料表後,再回傳一個多個資料表欄位的類別,如下程式查詢ProductEntityCategoryEntity,回傳ProductInfo

image

此時若要再透過前文的動態查詢欄位方法,則必須建立另一個類別才能達到,例 ProductXXXInfo.........,雖然只要新增一個類別再繼承ProductInfo即可以,但之後隨著系統發展越來越大的話,這種為了動態查詢建立的代理類別會越來越多..........。心想手動建立代理類別的方式可以是動態的嗎....?

  印象中EntityFramework預設就有使用代理類別來作LazyLoading機制,心想可以參考相關的作法來實作代理類別,在Google搜尋一下後,找到一篇使用ILGenerator來達到此功能。

   什麼是ILGenerator? 根據MSDN的介紹,可以透過它在執行時期產生 Microsoft Intermediate Language (MSIL) 指令,建立動態組件、方法和建構函式...等等 (詳原文)。

動態建立代理類別


  根據參考的文章及到MSDN硬K一下,將程式碼理解後再簡化如下(程式碼說明在註解上),ps:原作者的代理類別會將父類別的屬性及欄位作複製,我的需求較單純,只需回傳繼承的代理類別。
image

動態欄位查詢並回傳代理類別

前一篇文章的動態欄位查詢方法改成如下
1.改成泛型方法,2.回傳代理類別
image[19]

測試程式

   如下紅框只查詢2個欄位且回傳一樣可以用型別ProductInfo,這樣的測試或許比較看不出什麼效果,但若你用EntityFramework的Log或SqlProfile去觀察的話,就會看到執行的sql只會有你動態查詢的欄位,而不是所有欄位。
image

參考文章


http://www.cnblogs.com/why520crazy/articles/2781596.html(主要參考)
http://geekswithblogs.net/abhijeetp/archive/2010/04/04/a-simple-dynamic-proxy.aspx
http://www.codeproject.com/Articles/19513/Dynamic-But-Fast-The-Tale-of-Three-Monkeys-A-Wolf

範例程式

https://github.com/kimx/ExpressionLab
ps:請參考#region DynamicQueryProxy

這個網誌中的熱門文章

IIS 設定只允許特定IP進入