打造自己的LinqProvider
LinqProvider簡介
本篇假設讀者對Expression Tree 和Linq是有一定了解的,不了解的可以先看上面介紹Linq兩篇文章,補一下課。
首先我們來看一下LinQProvide是如何執行的:
簡單說明一下:我們寫的Linq查詢表達式將會被編譯為方法調用鏈,
然后每一個方法都會被編譯為一個相應的表達式樹,接下來所有的表達式樹會被組成為靜態調用鏈/表達式,
最后Provider的將這顆語法樹,翻譯為自己所需要的數據結構,比如ORM是翻譯為SQL語句,最后執行并返回結果。
事實上,編寫一個自己的LinqProvider是一件非常復雜的事情,大家可以看看微軟的官方示例:?演練:創建IQueryable LinQ提供程序
寫一個LinqProvider真是是很繁瑣,會有完全陷在linq的語法中、最后不知道自己在干嘛的感覺。這里的復雜性主要為以下三點:
1 同樣的方法可能來自于不同的ExressionTree,比如Select,可能來自于Select字句,也可能來自于let字句
2 語法解析會很快變得非常復雜(這點我深有體會),難以維護,程序的擴展性變得很難處理。
3 用戶可能自定義Linq的擴展,沒有準備好的LinqProvider的很可能會遇到錯誤,程序的健壯性得不到保障。
比如要你解析上面的這幅圖:
要讓一個Provider理解這個linq語法鏈,毫無疑問以現有的方式,真是蛋疼的要命。
難道我們沒有更智能的方式?
Re-Linq簡介
Re-Linq并不是要重新發明LinQ,其定位為?A General Purpose LINQ Foundation,With re-linq, it's now easier than ever to create full-featured LINQ providers。
你可能從來沒有聽說過Re-Linq,但是Re-Linq已經作為Entity FrameWork Core 和 NHibernate?的Linq Foundation而被使用,沒錯,這就是事實。
Re-Linq 官網 :https://relinq.codeplex.com/?,上面有關于Re-linq的簡介。
Re-Linq定位示意圖:
有了Re-linq之后,你不必再糾結那些復雜的語法樹,Re-linq將為你提供全新的接口和實現,實現一個自己的Linq-Provider從未變得如此簡單。讓我們從現在開始,進入正題。
打造自己的Linq Provider
他山之石,可以攻玉,下面我們借助于Re-Linq來實現自己的Linq-Provider.
我們新建一個項目,通過Nuget引入Re-linq:
接下來,分三步走:
第一步,實現自己的Queryable對象,只用繼承QueryableBase即可:
第二步,實現IQueryExecutor:
解釋一下:
ExcuteCollection方法將會在Linq的toList()等需要返回IEnumrable對象時被執行。
ExecuteScalar方法將會在比如Count()之類的方法被調用執行。
ExcuteSingle方法將會在First或者FirstOrDefault方法被調用時執行。
這三個接口可謂是Re-Linq對Linq語法樹最抽象的提煉,而所有的ExpressionTree數據都在方法的參數QueryModel中。
最后一部,訪問QueryModel,你需要定義自己的QueryModelVisitor,方法是繼承于QueryModelVisitorBase,接下來你會發現:?All you need is here:
你只需要重寫方法是繼承于QueryModelVisitorBase中的方法即可,你便可以訪問QueryModel所有已經解析并且歸類好了的數據結構了,譬如:
是不是非常清晰明了。
最后客戶端調用,:
Re-linq提供了LinqProvider的默認實現,而我們只需要用最少的代碼,實現我們的業務邏輯即可。雖然最后我們依然避不開解析Expresstree,
但是相對于之前的深陷代碼和概念泥潭,使用Re-linq無疑會讓你輕松很多。
更多的實現細節和理念請參考:
https://www.re-motion.org/blogs/mix/2009/09/02/how-to-write-a-linq-provider-the-simple-way?https://www.re-motion.org/blogs/mix/2009/09/02/how-to-write-a-linq-provider-the-simple-way-again/
最后附上Re-Linq白皮書:
https://www.re-motion.org/download/re-linq.pdf
原文地址:http://www.cnblogs.com/HouZhiHouJueBlogs/p/4610951.html
.NET社區新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注
總結
以上是生活随笔為你收集整理的打造自己的LinqProvider的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Aaron Stannard谈Akka.
- 下一篇: 使用Visual Studio 2015