个人心水论坛高手资料:LINQ 筆記

红姐心水论坛 www.lzuna.icu 8/3/2015來源:C#應用人氣:7464

LINQ 筆記

在LINQ開發當中var關鍵字顯得特別的重要,當你聲明一個var類型的變量時候,系統是不知道當前的類型,只有當你第一次為其賦值的時候,會根據其值來設置相應的數據類型,在LINQ查詢通常不知道返回的類型,所以將查詢到的結果放到var類型的變量當中 。

比如:

Var myInt=0;//在編譯的時候會自動將其轉成int類型

Var myBool=true;//編譯的時候會將其轉成bool類型

Var myString=”ime,marcheson”//編譯時自動將其轉成string類型

class LowNums

{

static void Main()

{

// A simple data source.

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

// Create the query.

// lowNums is an IEnumerable<int>

IEnumerable lowNums = from num in numbers

where num < 5

select num;

// Execute the query.

foreach (int i in lowNums)

{

Console.Write(i + " ");

}

}

}

通過上面紅色標記的那行就可以看出標準的LINQ語句通常包含from in where select這幾個關鍵字,大家是不是感覺跟sql的語句很像,但是倘若你真拿SQL的語句來用一定會非常懊惱,因為他看似一樣但實際上卻是完全不同的兩種標準,我們 將LINQ查詢操作符,通過表格的形式列出來,如下。

查詢操作符

含義

from 、in

用于定義任何LINQ表達式的主干,允許從合適的窗口中提取數據子集

where

用于定義從一個容器里取出哪些項的限制條件

select

用于從容器中選擇一個序列

join、on、equals、into

基于指定的鍵來做關鍵操作。記住,這些“關聯”不必與關系數據庫的數據有關系

ordderby、ascending、descending

允許結果子集按升序和降序排序

group、by

用特定的值來對數據分組后得到一個子集

上面的通常 是創建一個查詢,查詢的結果為少于5的項,并且對其進行輸出 。

在進行下面的知識之前一定要先了解IEnumerable和foreach這兩個簡單的概念。IEnumerable其實在C#是一個接口,在這個接口里面定義了一個方法GetEnumerator,這個方法的作用是返回一個循環訪問集合的枚舉器。這句話什么意義呢?就是當你的某一個對象繼承于這個接口,那么這個對象就可以通過foreach來進行遍歷,每次遍歷就相當于調用GetEnumerator讀取當前坐標的值并且定位到下一個坐標的位置。如我們常用的Array和list其實都是繼承了這個接口的,那么只要定義這兩個對象的時候選定相應的數據類型,并可以直接通過foreach來遍歷組內的元素。

很多時候我們不知道返回的數據類型,那么最好的變法是將其定義成var類型,那么用戶在通過foreach遍歷的時候也將其改成var類型

class LowNums

{

static void Main()

{

// A simple data source.

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

// Create the query.

// lowNums is an IEnumerable<int>

var lowNums = from num in numbers

where num < 5

select num;

// Execute the query.

foreach (var i in lowNums)

{

Console.Write(i + " ");

}

}

}

Linq字句返回的是Enumerable對象,所以當你用LINQ查詢的時候,可以在其外部調用Enumerable類的擴展方法。比如下面的查詢可以通過調用ToArray<int>()和ToList<int>方法將查詢到的結果,轉換成相應類型的容器當中 。

int[] numbers = { 10, 20, 30, 40, 1, 2, 3, 8 };

int[] subsetAsIntArray = (from i in numbers where i < 10 select i).ToArray<int>();

List<int>subsetAsListOfInts=(from i in numbers where i<10 select i).ToList<int>();

Linq除了從簡單的數組組里抽出結果以外,也可以操作System.Collections.Generic命名空間中的成員類型的數據,比如我們定義一個Car類。

public class Car

{

public string PetName { get; set; }

public string Color { get; set; }

public int Speed { get; set; }

public string Make { get; set; }

}

緊接著我們在main函數里面,創建一個List集合,集合的類型為car.

List<Car> myCars=new List<Car>(){

new Car{PetName="Henry",Color="Silver",Speed=100,Make="BMW"},

new Car{PetName="Daisy",Color="Tan",Speed=90,Make="BMW"},

new Car{PetName="Mary",Color="Black",Speed=55,Make="VW"},

new Car{PetName="Clunker",Color="Rust",Speed=5,Make="Yugo"},

new Car{PetName="Melvin",Color="White",Speed=43,Make="Ford"}

};

這里我們就可以通過linq對其進行操作,比如我們可以可以查詢其Speed大于等于55小于等于100,并且Make為BMW的值,我們可以通過以下語句來查詢;

var fastCars = from c in myCars where c.Speed >= 55 &&c.Speed<=100&& c.Make == "BMW" select c;

foreach(var car in fastCars)

{

Console.WriteLine(car.PetName);

}

這里我們發現對泛型容器的使用跟簡單的數組沒有什么區別,之前我們談到泛型胡處理,那么是否非泛型的不能處理,答案當然不是,在C#里面提供一個ofType<T>()方法來將當前胡對象轉化成一個一個兼容于IEnumerable<T>的對象。

static void LINQOverArrayList()

{

Console.WriteLine("***** LINQ over ArrayList*****");

ArrayList myCars = new ArrayList()

{

new Car{PetName="Henry",Color="Silver",Speed=100,Make="BMW"},

new Car{PetName="Daisy",Color="Tan",Speed=90,Make="BMW"},

new Car{PetName="Mary",Color="Rust",Speed=55,Make="VW"}

};

var myCarsEnum=myCars.OfType<Car>();

var fastCars = from c in myCarsEnum where c.Speed >= 55 select c;

foreach(var car in fastCars)

{

Console.WriteLine("{0},is going to fast!", car.PetName);

}

}

對表達式進行排序

查詢表達式中我們通過orderby來對數據進行排序,排序默認按正序進行排序。你可以通過ascending操作符號來指定為正序排序,也可改為descending來進行逆序排序。

正序:

Var subset=from p in PRoducts orderby p.Name ascending select p;

逆序:

Var subset=from p in products orderby p.Name descending select p;

Enumerable還提供了一個擴展方法,可以對兩個(或多個)LINQ查詢的數據進行合并(union)比較(difference)、連接(concatenation)和交叉(intersection)。

Except()擴展方法,它返回含兩個容器不同之處的LINQ集合集。下面的函數返回的只有一個”Yugo”

static void DisplayDiff()

{

List<string>myCars=new List<string>{"Yugo","Aztec","BMW"};

List<string> yourCars = new List<string> { "BMW", "Saab", "Aztec" };

var carDiff = (from c in myCars select c).Except(from c2 in yourCars select c2);

Console.WriteLine("Here is what ou don't have,but I do:");

foreach (string s in carDiff)

Console.WriteLine(s);

}

Intersect()方法返回兩個容器中共同的數據項。將上面的程序修改一下,返回的將是”Aztec”、”BMW”

static void DisplayIntersection()

{

List<string> myCars = new List<string> { "Yugo", "Aztec", "BMW" };

List<string> yourCars = new List<string> { "BMW", "Saab", "Aztec" };

var carDiff = (from c in myCars select c).Intersect(from c2 in yourCars select c2);

Console.WriteLine("Here is what ou don't have,but I do:");

foreach (string s in carDiff)

Console.WriteLine(s);

}

Union()是將多個結果合并成一個,如果有相同的成員只返回一個結果。下面的程序返回的是Yugo、Aztec、BMW、Saab

static void DisplayUnion()

{

List<string> myCars = new List<string> { "Yugo", "Aztec", "BMW" };

List<string> yourCars = new List<string> { "BMW", "Saab", "Aztec" };

var carDiff = (from c in myCars select c).Union(from c2 in yourCars select c2);

Console.WriteLine("Here is what ou don't have,but I do:");

foreach (string s in carDiff)

Console.Wr