Linq查詢的原理
我們?cè)趯W(xué)習(xí)Linq的時(shí)候會(huì)見到一些很常見的關(guān)鍵詞語(yǔ)。比如Linq To SQL、Linq To Objects、Linq To XML等。事實(shí)這些一般都是根據(jù)不同的數(shù)據(jù)源來(lái)進(jìn)行命名的。 說(shuō)實(shí)話筆者當(dāng)初學(xué)習(xí)的時(shí)候,看到這些命名險(xiǎn)些以為只有這幾種。事實(shí)不是這樣子的。Linq有倆個(gè)核心類——Enumerable類和Queryable類。這倆個(gè)類可以說(shuō)貫穿整個(gè)Linq知識(shí)體系。如果有心的朋友可以點(diǎn)開對(duì)應(yīng)的dll包就是發(fā)現(xiàn)他們都在System.Linq命名空間下。同時(shí)他們都是用于擴(kuò)展相應(yīng)的靜態(tài)方法。而且方法名大至相同。然后他們卻在本質(zhì)上有著細(xì)微的差別。Enumerable類是對(duì)IEnumerable<T>接口進(jìn)行擴(kuò)展并且傳入了Func類型的參數(shù)。數(shù)據(jù)源是來(lái)自于內(nèi)存中的。而Queryable類是對(duì)IQueryable<T>接口進(jìn)行擴(kuò)展,傳入?yún)?shù)是表達(dá)式(Expression類型)。數(shù)據(jù)源是來(lái)自于第三方。比如SQL Server、MySql等。
Linq的思想就是提供一個(gè)統(tǒng)一模型操作來(lái)處理數(shù)據(jù)。所以本質(zhì)來(lái)講對(duì)數(shù)據(jù)源不是很講究。比如數(shù)據(jù)源是文件,或則說(shuō)數(shù)據(jù)源是Excel之類的。相信可能有人已經(jīng)看到過(guò)Linq To Excel呢?主要辛苦還是這些開發(fā)底層的人。對(duì)于使用者來(lái)講沒(méi)有什么多大的差別。Linq現(xiàn)在面對(duì)數(shù)據(jù)源而擴(kuò)展功能有很多。其中專對(duì)數(shù)據(jù)庫(kù)來(lái)講,最流行還是有Linq To SQL。而且擴(kuò)展數(shù)據(jù)庫(kù)的Linq功能大多數(shù)都用IQueryable<T>接口。當(dāng)然,這不是說(shuō)用IEnumerable<T>接口就不行了。只是這倆種接口在實(shí)現(xiàn)上有著很大的差別。IEnumerable<T>接口我們都知道他一般是專對(duì)于內(nèi)存的。這意味著我們必須把相應(yīng)的數(shù)據(jù)全部加載到內(nèi)存中才可以進(jìn)行查詢。這樣子的操作太傷性能了。而IQueryable<T>接口我們可以巧妙的用上表達(dá)式樹(Expression Tree)進(jìn)行轉(zhuǎn)化生成對(duì)應(yīng)的數(shù)據(jù)庫(kù)SQL語(yǔ)句,然后在執(zhí)行數(shù)據(jù)庫(kù)。這才是顯得合理。
ORM思想能流行大體上可以說(shuō)是因?yàn)樗乃枷敫淤N切于人類的思維方式。在筆者看來(lái)如果把Linq技術(shù)說(shuō)成也是ORM思想的產(chǎn)物之一,這樣子的說(shuō)法也不為過(guò)。這也是筆者喜歡Linq的地方。LinqToDB框架只所以都能支持Linq。不可否認(rèn)也是依據(jù)這一種上面所講的原理來(lái)實(shí)現(xiàn)的。大體的想法如下。
- 實(shí)現(xiàn)Linq提供的IQueryable<T>接口和IQueryProvider接口。生成相關(guān)的表達(dá)式樹。
- 把對(duì)應(yīng)的表達(dá)式樹轉(zhuǎn)化生成對(duì)應(yīng)數(shù)據(jù)庫(kù)的SQL語(yǔ)句。并執(zhí)行。
- 根據(jù)映射的信息,生成對(duì)應(yīng)的集合類。(這里的集合類是指SQL語(yǔ)句執(zhí)行結(jié)果轉(zhuǎn)成類放入的集合)
實(shí)現(xiàn)自定義的Linq查詢一定離不開倆類——IQueryable<T>接口和IQueryProvider接口。上面的工作可以說(shuō)都在這倆類上面。IQueryable<T>接口一般用于生成對(duì)應(yīng)的表達(dá)式樹。而IQueryProvider接口用于執(zhí)行表達(dá)式樹,轉(zhuǎn)化成對(duì)應(yīng)的SQL語(yǔ)句,執(zhí)行數(shù)據(jù)庫(kù)并生成映射的模型對(duì)象。
注意:IQueryable<T>接口是什么樣子生成相關(guān)的表達(dá)式樹呢?讓筆者來(lái)講的話,筆者覺(jué)得有一點(diǎn)浪費(fèi)時(shí)間。但是不要當(dāng)心博客園里面有一位大神寫的博文一定能滿足你——王清培的《.NET深入解析LINQ框架》。
實(shí)現(xiàn)Linq查詢
支持Linq查詢本意上就是實(shí)現(xiàn)上面所講的倆個(gè)接口。當(dāng)你實(shí)現(xiàn)IQueryable<T>接口的時(shí)候,VS提示你實(shí)現(xiàn)三個(gè)屬性。如果你F12進(jìn)去查看他有些什么內(nèi)容的話,你會(huì)發(fā)現(xiàn)什么也沒(méi)有。為了方便筆者還是把他貼出來(lái)了。
IQueryable<T>接口:
延伸閱讀
- ssh框架 2016-09-30
- 阿里移動(dòng)安全 [無(wú)線安全]玩轉(zhuǎn)無(wú)線電——不安全的藍(lán)牙鎖 2017-07-26
- 消息隊(duì)列NetMQ 原理分析4-Socket、Session、Option和Pipe 2024-03-26
- Selective Search for Object Recognition 論文筆記【圖片目標(biāo)分割】 2017-07-26
- 詞向量-LRWE模型-更好地識(shí)別反義詞同義詞 2017-07-26
- 從棧不平衡問(wèn)題 理解 calling convention 2017-07-26
- php imagemagick 處理 圖片剪切、壓縮、合并、插入文本、背景色透明 2017-07-26
- Swift實(shí)現(xiàn)JSON轉(zhuǎn)Model - HandyJSON使用講解 2017-07-26
- 阿里移動(dòng)安全 Android端惡意鎖屏勒索應(yīng)用分析 2017-07-26
- 集合結(jié)合數(shù)據(jù)結(jié)構(gòu)來(lái)看看(二) 2017-07-26