<a href="http://www.cnblogs.com/wolf-sun/p/4230226.html#t1" target="_blank">寫在前面</a>
<a href="http://www.cnblogs.com/wolf-sun/p/4230226.html#t2" target="_blank">系列文章</a>
<a href="http://www.cnblogs.com/wolf-sun/p/4230226.html#t3" target="_blank">表達式樹解析</a>
<a href="http://www.cnblogs.com/wolf-sun/p/4230226.html#t4" target="_blank">表達式樹特性</a>
<a href="http://www.cnblogs.com/wolf-sun/p/4230226.html#t5" target="_blank">編譯表達樹</a>
<a href="http://www.cnblogs.com/wolf-sun/p/4230226.html#t6" target="_blank">總結</a>
讓我們首先簡單回顧一下上篇文章介紹的内容,上篇文章介紹了表達式樹的基本概念(表達式樹又稱為“表達式目錄樹”,以資料形式表示語言級代碼,它是一種抽象文法樹或者說是一種資料結構),以及兩種建立表達式樹目錄樹的方式:以lambda表達式的方式建立,通過api靜态方法建立。由于不能将有語句體的lambda表達式轉換為表達式樹,而有時我們又有這樣的需求,那麼這種情況你可以選擇api的靜态方法方式建立,在 .net framework 4 中,api 表達式樹還支援指派表達式和控制流表達式,比如循環、條件塊和 try-catch 塊等。
<a href="http://www.cnblogs.com/wolf-sun/p/4199383.html">linq之lambda表達式初步認識</a>
<a href="http://www.cnblogs.com/wolf-sun/p/4206982.html">linq之lambda進階</a>
<a href="http://www.cnblogs.com/wolf-sun/p/4214164.html">linq之隐式類型、自動屬性、初始化器、匿名類</a>
<a href="http://www.cnblogs.com/wolf-sun/p/4216256.html">linq之擴充方法</a>
<a href="http://www.cnblogs.com/wolf-sun/p/4222473.html">linq之expression初見</a>
我們可以通過api方式建立表達式樹,那麼我們有沒有辦法,将給定的表達式樹進行解析,分别得到各個部分呢?答案是肯定,下面看一個例子。
有一個這樣的表達式樹
可以這樣來解析,分别得到各個部分


輸出結果
是不是很爽?不知道到這裡,你是否對orm架構中,lambda表達式是如何轉化為sql語句有那麼一點點的靈感?沒有沒關系,咱們繼續看一個例子。如果資料庫中有person這樣的一個資料表。咱們項目中有對應的person這樣的一個持久化類。那麼我們建立一個這樣的一個查詢方法,傳回所有齡大于等于18歲的成年人的sql語句。


是不是很友善?傳進來一個lambda表達式,就可以通過orm架構内部解析,然後轉化為sql語句。也就是通過編寫lambda就等于寫了sql語句,也不用擔心不會寫sql語句了。
表達式樹應具有永久性。 這意味着如果你想修改某個表達式樹,則必須複制該表達式樹然後替換其中的節點來建立一個新的表達式樹。
那如何修改呢?
可以通過 expressionvisitor類周遊現有表達式樹,并複制它通路的每個節點。
一個例子
在項目中添加一個andalsomodifier 類。
将表達式樹中的andalse修改為orelse,代碼如下:


測試代碼


小結:修改表達式樹,需繼承expressionvisitor類,并重寫它的visitbinary(如果是類似and這類的二進制表達式)方法。再舉一個例子,如果要将大于修改為小于等于,可修改visitbinary方法的實作。


結果
expression<tdelegate> 類型提供了 compile 方法以将表達式樹表示的代碼編譯成可執行委托。
還以最上面的那個表達式樹為例
有這樣的一個表達式樹,現在,我想直接輸入一個值,然後得到結果,該如何辦呢?可以這樣


1.通過表達式解析,你可以得到表達式樹的各個部分。你會發現如果你寫的方法的參數是expression<func<t,t>>類型的,你可以更好的使用lambda表達式的特性,操作更友善。例子中,也簡單分析了,orm架構中,是如何将lambda表達式解析為sql語句的,也希望能激發你的興趣。
2.表達式樹具有永久性的特性,一經建立,如果你想修改某個表達式樹,則必須複制該表達式樹然後替換其中的節點來建立一個新的表達式樹。具體操作可參考上面的例子。
3.通過complie方法編譯後的表達式樹,就是一個委托,委托對應的方法的方法體就是表達式樹中的lambda表達式,你可以像使用委托一樣去使用它。有時你嫌麻煩也可以類似這樣直接使用
參考文章
http://msdn.microsoft.com/zh-cn/library/bb397951.aspx
http://msdn.microsoft.com/zh-cn/library/bb546136.aspx
部落格位址:
<a href="http://www.cnblogs.com/wolf-sun">http://www.cnblogs.com/wolf-sun/</a>
部落格版權:
本文以學習、研究和分享為主,歡迎轉載,但必須在文章頁面明顯位置給出原文連接配接。
如果文中有不妥或者錯誤的地方還望高手的你指出,以免誤人子弟。如果覺得本文對你有所幫助不如【推薦】一下!如果你有更好的建議,不如留言一起讨論,共同進步!
再次感謝您耐心的讀完本篇文章。http://www.cnblogs.com/wolf-sun/p/4230226.html