C#語法之Linq查詢基礎一

Linq作.Net開發的應該都用過,有些地方很複雜的邏輯用Linq很方便的解決。對於Linq to object、Linq to xml、Linq to sql、Linq to Entity(EF)均可以使用linq查詢。不知道你們有沒有想過爲何linq對這些均可以使用呢?統一的api適用這麼多。其實主要仍是IEnummerable<T>和IQueryable<T>兩個接口。可能有人會問爲何是兩個接口?這兩個接口有什麼區別或者聯繫呢?這又要引出來Enummerable、Queryable兩個類。sql

1、IEnummerable<T>和IQueryable<T>區別api

using System.Runtime.InteropServices;

namespace System.Collections
{
    //
    // 摘要:
    //     公開枚舉數,該枚舉數支持在非泛型集合上進行簡單迭代。
    [ComVisible(true)]
    [Guid("496B0ABE-CDEE-11d3-88E8-00902754C43A")]
    public interface IEnumerable
    {
        //
        // 摘要:
        //     返回一個循環訪問集合的枚舉器。
        //
        // 返回結果:
        //     可用於循環訪問集合的 System.Collections.IEnumerator 對象。
        [DispId(-4)]
        IEnumerator GetEnumerator();
    }
}
using System.Collections;
using System.Linq.Expressions;

namespace System.Linq
{
    //
    // 摘要:
    //     提供對未指定數據類型的特定數據源的查詢進行計算的功能。
    public interface IQueryable : IEnumerable
    {
        //
        // 摘要:
        //     獲取在執行與 System.Linq.IQueryable 的此實例關聯的表達式目錄樹時返回的元素的類型。
        //
        // 返回結果:
        //     一個 System.Type,表示在執行與之關聯的表達式目錄樹時返回的元素的類型。
        Type ElementType { get; }
        //
        // 摘要:
        //     獲取與 System.Linq.IQueryable 的實例關聯的表達式目錄樹。
        //
        // 返回結果:
        //     與 System.Linq.IQueryable 的此實例關聯的 System.Linq.Expressions.Expression。
        Expression Expression { get; }
        //
        // 摘要:
        //     獲取與此數據源關聯的查詢提供程序。
        //
        // 返回結果:
        //     與此數據源關聯的 System.Linq.IQueryProvider。
        IQueryProvider Provider { get; }
    }
}

看它們兩個的定義也能看出IQueryable繼承IEnumerable,那二者什麼區別呢?那咱們能夠看下兩個接口的擴展類Enumerable、Queryable。數組

這兩個類API相同,可是仔細看能夠發現參數類型不同,一個是Fuc<> 一個是Expression<Fuc<>>,其實Queryable是對Linq to sql、EF來使用的,雖然對外的api是同樣的,但實現的原理是不同的,一個是func<>lamdbs表達式,一個是Expression<Fuc<>>表達式樹。ide

2、Linq基礎查詢ui

前面區分了兩個接口,但API是同樣的,查詢用法也是同樣,只是提升數據源的方式不同。因此先拋開不同的,求同存異嘛,下面主要是講一下同樣的部分。spa

上面是在百科上下的圖片,雖然我也沒看明白這個圖,但在下面的幾篇博客中我會把Linq查詢的基本用法都列舉出來,今天這篇博客只是對Linq作一簡單介紹。code

1.方法語法、查詢語法xml

書寫LINQ查詢時又兩種語法可供選擇:方法語法(Fluent Syntax)和查詢語法(Query Expression)。對象

LINQ方法語法是很是靈活和重要的,咱們在這裏將描述使用連接查詢運算符的方式來建立複雜的查詢,方法語法的本質是經過擴展方法和Lambda表達式來建立查詢。C# 3.0對於LINQ表達式還引入了聲明式的查詢語法,經過查詢語法寫出的查詢比較相似於SQL查詢。本篇會對LINQ方法語法進行詳細的介紹。blog

固然,.NET公共語言運行庫(CLR)並不具備查詢語法的概念。因此,編譯器會在程序編譯時把查詢表達式轉換爲方法語法,即對擴展方法的調用。因此使用方法語法會讓咱們更加接近和了解LINQ的實現和本質,而且一些查詢只能表示爲方法調用,如檢索序列中的最大值、最小值元素的查詢,他們在查詢語法中就沒有對應的實現。但另外一方面,查詢語法一般會比較簡單和易讀。無論怎樣,這兩種語法和互相補充和兼容的,咱們能夠在一個查詢中混合使用方法語法和查詢語法。

好比直接.List.where(p=>XX)這種是方法語法, from p in list XXXX這種是查詢語法,查詢語法仍是轉換爲方法語法。

2.延遲計算

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,照數組a中3的倍數的數字,輸出是二、九、6,但當把b改成2時,再次輸出結果發現輸出的是二、四、6,這個例子主要說明Linq是延遲計算,和其餘地方的懶加載是同樣的,聲明的時候並不會直接計算出來,而是等到用時在計算。

相關文章
相關標籤/搜索