C#语法之Linq查询基础一
Linq做.Net開發(fā)的應(yīng)該都用過,有些地方很復(fù)雜的邏輯用Linq很方便的解決。對(duì)于Linq to object、Linq to xml、Linq to sql、Linq to Entity(EF)都可以使用linq查詢。不知道大家有沒有想過為什么linq對(duì)這些都可以使用呢?統(tǒng)一的api適用這么多。其實(shí)主要還是IEnummerable<T>和IQueryable<T>兩個(gè)接口。可能有人會(huì)問為什么是兩個(gè)接口?這兩個(gè)接口有什么區(qū)別或者聯(lián)系呢?這又要引出來Enummerable、Queryable兩個(gè)類。
一、IEnummerable<T>和IQueryable<T>區(qū)別
using System.Runtime.InteropServices;namespace System.Collections {//// 摘要:// 公開枚舉數(shù),該枚舉數(shù)支持在非泛型集合上進(jìn)行簡(jiǎn)單迭代。[ComVisible(true)][Guid("496B0ABE-CDEE-11d3-88E8-00902754C43A")]public interface IEnumerable{//// 摘要:// 返回一個(gè)循環(huán)訪問集合的枚舉器。//// 返回結(jié)果:// 可用于循環(huán)訪問集合的 System.Collections.IEnumerator 對(duì)象。[DispId(-4)]IEnumerator GetEnumerator();} } using System.Collections; using System.Linq.Expressions;namespace System.Linq {//// 摘要:// 提供對(duì)未指定數(shù)據(jù)類型的特定數(shù)據(jù)源的查詢進(jìn)行計(jì)算的功能。public interface IQueryable : IEnumerable{//// 摘要:// 獲取在執(zhí)行與 System.Linq.IQueryable 的此實(shí)例關(guān)聯(lián)的表達(dá)式目錄樹時(shí)返回的元素的類型。//// 返回結(jié)果:// 一個(gè) System.Type,表示在執(zhí)行與之關(guān)聯(lián)的表達(dá)式目錄樹時(shí)返回的元素的類型。Type ElementType { get; }//// 摘要:// 獲取與 System.Linq.IQueryable 的實(shí)例關(guān)聯(lián)的表達(dá)式目錄樹。//// 返回結(jié)果:// 與 System.Linq.IQueryable 的此實(shí)例關(guān)聯(lián)的 System.Linq.Expressions.Expression。Expression Expression { get; }//// 摘要:// 獲取與此數(shù)據(jù)源關(guān)聯(lián)的查詢提供程序。//// 返回結(jié)果:// 與此數(shù)據(jù)源關(guān)聯(lián)的 System.Linq.IQueryProvider。IQueryProvider Provider { get; }} }看它們兩個(gè)的定義也能看出IQueryable繼承IEnumerable,那兩者什么區(qū)別呢?那我們可以看下兩個(gè)接口的擴(kuò)展類Enumerable、Queryable。
這兩個(gè)類API相同,但是仔細(xì)看可以發(fā)現(xiàn)參數(shù)類型不一樣,一個(gè)是Fuc<> 一個(gè)是Expression<Fuc<>>,其實(shí)Queryable是對(duì)Linq to sql、EF來使用的,雖然對(duì)外的api是一樣的,但實(shí)現(xiàn)的原理是不一樣的,一個(gè)是func<>lamdbs表達(dá)式,一個(gè)是Expression<Fuc<>>表達(dá)式樹。
二、Linq基礎(chǔ)查詢
前面區(qū)分了兩個(gè)接口,但API是一樣的,查詢用法也是一樣,只是提高數(shù)據(jù)源的方式不一樣。所以先拋開不一樣的,求同存異嘛,下面主要是講一下一樣的部分。
上面是在百科上下的圖片,雖然我也沒看明白這個(gè)圖,但在下面的幾篇博客中我會(huì)把Linq查詢的基本用法都列舉出來,今天這篇博客只是對(duì)Linq做一簡(jiǎn)單介紹。
1.方法語法、查詢語法
書寫LINQ查詢時(shí)又兩種語法可供選擇:方法語法(Fluent Syntax)和查詢語法(Query Expression)。
LINQ方法語法是非常靈活和重要的,我們?cè)谶@里將描述使用鏈接查詢運(yùn)算符的方式來創(chuàng)建復(fù)雜的查詢,方法語法的本質(zhì)是通過擴(kuò)展方法和Lambda表達(dá)式來創(chuàng)建查詢。C# 3.0對(duì)于LINQ表達(dá)式還引入了聲明式的查詢語法,通過查詢語法寫出的查詢比較類似于SQL查詢。本篇會(huì)對(duì)LINQ方法語法進(jìn)行詳細(xì)的介紹。
當(dāng)然,.NET公共語言運(yùn)行庫(kù)(CLR)并不具有查詢語法的概念。所以,編譯器會(huì)在程序編譯時(shí)把查詢表達(dá)式轉(zhuǎn)換為方法語法,即對(duì)擴(kuò)展方法的調(diào)用。所以使用方法語法會(huì)讓我們更加接近和了解LINQ的實(shí)現(xiàn)和本質(zhì),并且一些查詢只能表示為方法調(diào)用,如檢索序列中的最大值、最小值元素的查詢,他們?cè)诓樵冋Z法中就沒有對(duì)應(yīng)的實(shí)現(xiàn)。但另一方面,查詢語法通常會(huì)比較簡(jiǎn)單和易讀。不管怎樣,這兩種語法和互相補(bǔ)充和兼容的,我們可以在一個(gè)查詢中混合使用方法語法和查詢語法。
比如直接.List.where(p=>XX)這種是方法語法, from p in list XXXX這種是查詢語法,查詢語法還是轉(zhuǎn)換為方法語法。
2.延遲計(jì)算
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace LinqDemo {class Program{static void Main(string[] args){int[] a = new int[] { 1,3,5,7,9,11,2,4,6};int b = 3;var result = from p in a where p % b == 0 select p;foreach (var m in result){Console.WriteLine(m);}Console.WriteLine("-------------------------");b = 2;foreach (var m in result){Console.WriteLine(m);}Console.ReadLine();}} }上面代碼第一次是b=3,照數(shù)組a中3的倍數(shù)的數(shù)字,輸出是2、9、6,但當(dāng)把b改為2時(shí),再次輸出結(jié)果發(fā)現(xiàn)輸出的是2、4、6,這個(gè)例子主要說明Linq是延遲計(jì)算,和其他地方的懶加載是一樣的,聲明的時(shí)候并不會(huì)直接計(jì)算出來,而是等到用時(shí)在計(jì)算。
轉(zhuǎn)載于:https://www.cnblogs.com/5ishare/p/5770369.html
總結(jié)
以上是生活随笔為你收集整理的C#语法之Linq查询基础一的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: redis pool
- 下一篇: C# 之浅拷贝与深拷贝问题拙见(一)