一、linq中的表達式和表達式樹
Linq中的表達式(Expression<TDel>)是強類型的lambda表達式,對Func和Action形式的委托做了一層封裝。
lambda表達式的本質是簡寫的匿名函數,可以賦值給Func或Action類型的委托,在.net中被編譯成可執行的代碼;lambda表達式賦值給Expression<TDel>>,.net將其轉換成表達式樹。
什么是表達式樹:
表達式樹是表達式的內存表示,保存了表達式的數據結構。如我們查詢年齡大於18歲的學生,使用lambda表達式為stu=>stu.Age>18,這個表達式會被.net轉化成一棵表達式樹:樹的每一個節點都是一個表達式,如輸入參數stu用ParameterExpression表示,18用ConstantExpression表示,具體如下圖(圖片來源:http://www.yuanjiaocheng.net/Linq/linq-expression-tree.html)
二、使用表達式樹的好處
表達式樹是完全透明的,方便了解參數和功能(EF中的Linq to Sql要把linq語句轉化成sql語句,lambda賦值給Func或者Action,其被轉換成可執行代碼,要把可執行代碼轉換成Sql很不方便,如果把lambda賦值給Expression,程序很方便的通過表達式樹獲取數據結構,從而使轉換sql時變得方便)
三、總結
linq中的表達式是對Func和Action形式的委托做了一層封裝,在內存中以表達式數形式存儲,這種存儲方式數據結構明了,有利於進行Linq to XXX查詢(如很容易將linq轉成sql)。還有一點linq查詢默認都是延遲加載的,只有使用結果時才執行真正的查詢操作(如 在執行first,last,single,count,ToList,toXXX時才進行真正的查詢),這種設計將查詢的方式和查詢的執行進行了 解耦,使得我們可以將查詢方法分成多個步驟來創建,linq表達式的保存這些查詢方法(就是封裝的委托),在我們需要使用查詢結果時,通過一個完整的方法(linq表達式組合在一起)去查詢,減少了對集合的查詢次數,這種特性對數據庫查詢很有利。(如我們在進行用戶和用戶角色聯合查詢時,先獲取IEnumerable<User>和IEnumerable<Role>,在通過Linq的聯結查詢獲取結果,其實只查了一次數據庫)。