Linq 學習筆記(一)

來源:互聯網
上載者:User

一·前言

Linq 英文全稱Language Integrated Query,它提供了C#程式設計語言中的查詢文法,可以使用相同的文法訪問不同的資料來源。並且Linq還提供了不同資料來源的抽象層,所以可以使用相同的文法。本次筆記的主要內容如下:

● 用List<T>在對象上執行傳統查詢
● 擴充方法
● λ運算式
● LINQ 查詢
● 標準查詢操作符
● 運算式樹狀架構
● LINQ 提供者

 

一。用List<T>在對象上執行傳統查詢

首先我們來看一個最簡單的例子,請看下面的代碼:

            List<string> strList = new List<string>();

            strList.Add("AAA");

            strList.Add("BABB");

            strList.Add("ACCC");

            strList.Add("BBB");

            strList.Add("CCC");

            var res = strList.FindAll(delegate(string s) { return s.Contains("A"); });

            res.Sort(delegate(string a, string b) { return a.CompareTo(b); });

            this.GridView1.DataSource = res;

            this.GridView1.DataBind();

這段代碼是從strList中尋找所有包含字母A的記錄,並且將得到的結果進行進行從小到大的排序(如果將return a.CompareTo(b); 換成return b.CompareTo(a);結果則是從大到小的順序進行排列了)。相信很多人用過這樣的方式來對結果集進行過濾和排序操作。但是如果你想在任何集合都可以使用這兩個方法,那你就可能會使用到擴充方法了。擴充方法是C#3.0的新增特性,這也是上述例子邁向LINQ 的第一個變化。下面我們就來介紹一下擴充方法。

二。擴充方法

 請看下面關於擴充方法的例子

public static class helper

    {

        public static string MD5Hash(this string s)

        {

            return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(s, "MD5");

        }

        public static bool In(this object o, IEnumerable b)

        {

            foreach (object obj in b)

            {

                if (obj == o)

                    return true;

            }

            return false;

        }

    }

    // 調用擴充方法

    Response.Write("123456".MD5Hash());

    Response.Write("1".In(new[]{"1","2","3"}));

上面的例子是對string進行了擴充,這樣的話只要在當前命名空間下任何string對象都可以利用該擴充方法。這樣會給代碼帶來很大的方便。

既然有了擴充方法,我們的Linq自然就很容易就出現了。就如同下面的Linq例子一樣

          MethodInfo[] methods = typeof(string).GetMethods();

            var result = from m in methods

                         where m.IsStatic != true

                         select m.Name;

            foreach (var r in result)

            {

                Response.Write(r.ToString()+"<br/>");

            }

這就是Linq最典型的樣子。是不是比較像我們平時用的SQL呢?呵呵雖然還有不小的差別,但是Linq的引入實在是C#的一種革命性的變化。他不僅好用,更給枯燥的C#代碼注入了一股鮮活的思想。

三。λ運算式

 C# 3.0 給匿名方法提供了一個新的文法——λ運算式(也叫做Lambda運算式)。除了把匿名方法傳送給Where()、OrderbyDescen
ding()和Select()方法之外,還可以使用λ運算式。
λ 運算式參見第7 章。λ運算式在LINQ 中非常重要,所以下面複習一下該文法。詳細資料可參見第7
章。
比較λ運算式和匿名委託,會發現許多類似之處。λ運算子=>的左邊是參數,不需要添加參數類型,因
為它們是由編譯器解析的。λ運算子的右邊定義了執行代碼。在匿名方法中,需要花括弧和return 語句。在
λ運算式中,不需要這些文法元素,因為它們是由編譯器處理的。如果λ運算子右邊有多個語句,也可以使
用花括弧和return 語句。
例如下面的例子

  var list = new[] { "aa", "bb", "ca" };

  var resultList = Array.FindAll(list, s => (s.IndexOf("a") > -1));

  foreach (var v in resultList)

      Response.Write(v+"<br/>");

s就像是我們在第一個例子中使用的delegate(string s)裡面的s一樣只是這種使用方法更加的靈活和方便。

四。LINQ 查詢

我們就以NorthWind資料庫為例,添加一個Linq to Sql Classes命名為Customer.dbml,然後開啟Server Explorer設定好串連參數,選擇Customers表直接拖拽到Customer.dbml,開啟Customer.design.cs檔案我們可以看到Visual Studio為我們產生了很多代碼。這些代碼我們會在後面的內容裡詳細的講解。現在主要來講一下Linq查詢以及後面的內容。

LINQ 查詢是C#語言中的一個簡化查詢記號。編譯器編譯查詢運算式,調用擴充方法。查詢運算式只是C#中的一個文法,但不需要修改底層的IL 代碼。查詢運算式必須以from子句開頭,以select或group子句結束。在這兩個子句之間,可以使用where、orderby、join、let 和其他from子句。注意,變數query只指定了LINQ查詢。該查詢不是通過這個指派陳述式執行的,只要使用foreach逐一查看查詢,該查詢就會執行。

延遲查詢的執行

在運行期間定義查詢運算式時,查詢就不會運行。查詢會在迭代資料項目時運行。再看看擴充方法Where()。它使用yield return語句返回謂詞為true的元素。因為使用了yield return語句,所以編譯器會建立一個列舉程式,在訪問枚舉中的項後,就返回它們。

        public static IEnumerable<T> Where<T>(this IEnumerable<T> source,Func<T, bool> predicate)

        {

            foreach (T item in source)

                if (predicate(item))

                    yield return item;

        }

請看一下下面的代碼

var names = new List<string>{"Nino","Alberto", "Juan", "Mike", "Phil"};
            var namesWirhJ = (from name in names where name.StartsWith("J") orderby name select name);
            Response.Write("First Iteration<br/>");
            foreach (var name in namesWirhJ)
                Response.Write(name + "<br/>");
            names.Add("John");
            names.Add("Jim");
            names.Add("Jack");
            names.Add("Denny");
            Response.Write("Second iteration<br/>");
            foreach (var name in namesWirhJ)
                Response.Write(name + "<br/>");

其返回結果為

First iteration
Juan
Second iteration
Jack
Jim
John
Juan

但是當我們修改一下代碼將 var namesWirhJ = (from name in names where name.StartsWith("J") orderby name select name);換做var namesWirhJ = (from name in names where name.StartsWith("J") orderby name select name).ToList();那麼結果就成了

First iteration
Juan
Second iteration
Juan

這就是我們需要注意的地方了,每次在迭代中使用查詢時,都會調用擴充方法。在大多數情況下,這是非常有效,因為我們可以檢測出來源資料中的變化。但是在一些情況下,這是不可行的。調用擴充方法ToArray()、ToEnu
merable()、ToList()等可以改變這個操作。這也就是為什麼我們需要示範ToList()方法了。ToList 迭代集合,返回一個實現了List<string>的集合。之後對返回的列表迭代兩次,在這個過程中,資料來源被修改了,但是原來的集合并沒有改變。這樣可以用來實現一些比較複雜的商務邏輯。

五。標準查詢操作符

Where、OrderByDescending 和Select 只是LINQ 的幾個查詢操作符。LINQ 查詢為最常用的操作符定
義了一個聲明文法。還有許多標準查詢操作符。下表列出了Linq的標準查詢操作符。

 

Where

OfType<TResult>

過濾操作符定義了返回元素的條件。在Where 查詢操作符中,可以使用謂詞,

例如λ運算式定義的謂詞,來返回布爾值。OfType<TResult>根據類型過濾元素,只

返回TResult 類型的元素

Select和SelectMany

投射操作符用於把對象轉換為另一個類型的對象。Select 和SelectMany 定義

了根據選取器函數選擇結果值的投射

OrderBy,ThenBy

OrderByDescending

ThenByDescending

Reverse

排序操作符改變所返回的元素的順序。OrderBy 按升序排序,

OrderByDescending 按降序排序。如果第一次排序的結果很類似,就可以使用

ThenBy 和ThenBy Descending 操作符進行第二次排序。Reverse 反轉集合中元

素的順序

Join,GroupJoin

串連運算子用於合并不直接相關的集合。使用Join 操作符,可以根據鍵選擇

器函數串連兩個集合,這類似於SQL 中的JOIN。GroupJoin 操作符串連兩個集

合,組合其結果

GroupBy

組合運算子把資料放在組中。GroupBy 操作符組合有公用鍵的元素

Any,All,Contains

如果元素序列滿足指定的條件,量詞操作符就返回布爾值。Any,All 和Contains

都是量詞操作符。Any 確定集合中是否有滿足謂詞函數的元素;All 確定集合

中的所有元素是否都滿足謂詞函數;Contains 檢查某個元素是否在集合中。這些操作

符都返回一個布爾值

Take,Skip,

TakeWhile

SkipWhile

分區操作符返回集合的一個子集。Take、Skip、TakeWhile 和SkipWhile 都是

分區操作符。使用它們可以得到部分結果。使用Take 必須指定要從集合中提

取的元素個數;Skip 跳過指定的元素個數,提取其他元素,TakeWhile 提取條件為真的

元素

Distinct,Union

Intersect,Except

Set 操作符返回一個集合。Distinct 從集合中重複資料刪除的元素。除了Distinct

之外,其他Set 操作符都需要兩個集合。Union 返回出現在其中一個集合中的

元素。Intersect 返回兩個集合中都有的元素。Except 返回只出現在一個集合

中的元素

First

FirstOrDefault

Last

LastOrDefault

ElementAt

ElementAtOrDefault

Single

SingleOrDefault

這些元素操作符僅返回一個元素。First 返回第一個滿足條件的元素。

FirstOrDefault 類似於First,但如果沒有找到滿足條件的元素,就傳回型別

的預設值。Last 返回最後一個滿足條件的元素。ElementAt 指定了要返回的元

素的位置。Single 只返回一個滿足條件的元素。如果有多個元素都滿足條件,

就拋出一個異常

Count,Sum,Min,

Max,Average,

Aggregate

合計操作符計算集合的一個值。利用這些合計操作符,可以計算所有值的總和、

元素的個數、值最大和最小的元素,平均值等

ToArray

ToEnumerable

ToList

ToDictionary

toType<T>

這些轉換操作符將集合轉換為數組、IEnumerable、IList、IDictionary 等

Empty,Range,

Repeat

這些產生操作符返回一個新集合。使用Empty,集合是空的,Range 返回一系列數

字,Repeat 返回一個始終重複一個值的集合

註:本文內容摘自http://blog.sina.com.cn/s/blog_5df2629a0100lr3u.html

 

ASP.NET開發技術交流群: 67511751(人員招募中...)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.