我們知道實現(xiàn)了IQueryable<T>接口和IQueryProvider接口就可以使用Linq To SQL的功能。關(guān)于如何去實現(xiàn)的話,上一章也為我們引導了一個方向。LinqToDB框架也是順著這個方向進行的。然而筆者對LinqToDB框架的作者真的很無語。如果有打開過LinqToDB框架源碼的朋友,可能會發(fā)現(xiàn)很多代碼都沒有文字說明。這無疑給那些想要深入了解框架的人加大了前進力度。本來筆者以為只是沒有相關(guān)代碼說明不用怕。只要找到對應(yīng)的文檔應(yīng)該沒有什么大問題。于是筆者也跟很多人一樣子——去作者的github上找。結(jié)果只有教大家如何使用。卻對框架沒有進行任何說明。筆者又想也許作者比較懶吧??赡苤挥性谒牟┛蜕喜庞邢嚓P(guān)的文檔吧。結(jié)果筆者很失望——沒有找到任何有幫助的東西。唉!為了能獲得更多的資料筆者還購買了VPN。所以想要了解LinqToDB框架只有一個方式——硬著頭皮啃代碼。顯然這種做法就是從代碼中尋找作者的思路和理念。同時不可否認存在猜測上的錯誤。必竟作者的隨意一段代碼就有可能導至理解上的誤導。希望讀者們能夠理解。

LinqToDB框架的原理


正如上面所講的,LinqToDB框架也是按上一章中講到的三個大至步驟進行的。所以我們的目標也變得很明確——了解LinqToDB框架是如何實現(xiàn)這三大步驟的。

1.實現(xiàn)Linq提供的IQueryable<T>接口和IQueryProvider接口。生成相關(guān)的表達式樹。
2.把對應(yīng)的表達式樹轉(zhuǎn)化生成對應(yīng)數(shù)據(jù)庫的SQL語句。并執(zhí)行。
3.根據(jù)映射的信息,生成對應(yīng)的集合類。

從上一章的例子中我們可以看到LinqToDB框架以DataContext類作為入口類。這一點顯然跟Entity Framework一樣子。都是以某個類做為上下文引動整個框架。如果你們看過github上的例子的話,就會發(fā)現(xiàn)筆者用的入口類跟作者不太一樣子。作者用的是DataConnection類。事實上不管是DataConnection類還是DataContext類他們都繼承了IDataContext接口。所以在使用上來講,不會差太多。只是在筆者看來他們之間的職責卻存在很大的差別。不過筆者還是不太明白作者這樣子設(shè)計的目的。DataConnection類能做DataContext類的大部分事情,卻又擁有自己獨有的職責——負責存取當前數(shù)據(jù)庫的信息。讓筆者感覺DataConnection類在職責上有一點重復了。這也是為什么筆者認為DataContext類才是LinqToDB框架入口類。至少讓筆者覺得DataContext類比較明確。

 

上面這張圖片是描述了LinqToDB框架在查詢時候的一個原理圖。是筆者根據(jù)代碼的運行路線整理出來的。主要的目地就是為了方便導引大家深入,少走一點彎路。我們知道要實現(xiàn)Linq查詢很簡單,就是上面的三個步驟??墒且獙崿F(xiàn)這三個步驟的事情卻很多。圖片上只是顯示主要核心類切口。可以說這三個步驟就是靠圖片上的類進行工作的。

加載數(shù)據(jù)數(shù)庫信息

LinqToDB框架并沒有直接就將實現(xiàn)IQueryable<T>和IQueryProvider的類交出來。而是以上下文的思維方式間接性的引導出來。這也是合理的設(shè)計。必竟在生成表達式樹和SQL語句之前,我們有必要知道數(shù)據(jù)庫的相關(guān)信息。比如當前數(shù)據(jù)庫是用什么——Sql Server還是MySql。而這個工作任務(wù)交給圖中的DataConnection。這味意著LinqToDB框架在進入上面所講的第一步的時候,就已經(jīng)知道數(shù)據(jù)庫的信息了。但是作者并沒有直接性的設(shè)置數(shù)據(jù)庫的信息。而是通過IDataProvider接口實例來提供。這樣子更加區(qū)別出DataContext類只是用于引導的職責。如果你們使用過增刪改的話,你們可能會覺得不對。他不是可以會增刪改嗎?事實上如果你們用心點的話,就會現(xiàn)他們都是靜態(tài)擴展方法。

網(wǎng)友評論