LINQ教程一:LINQ簡(jiǎn)介一、為什么要使用LINQ 要理解為什么使用LINQ,先來看下面一個(gè)例子。假設(shè)有一個(gè)整數(shù)類型的數(shù)組,找到里面的偶數(shù)并進(jìn)行降序排序。 在C#2.0以前,如果要實(shí)現(xiàn)這樣的功能,我們必須使用'foreach'或'for'循環(huán)來遍歷數(shù)組,先找到偶數(shù)然后在降序排序,相關(guān)代碼如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;
namespace LinqOfSelectOperation { class Program { static void Main(string[] args) { // 查詢出數(shù)組中的偶數(shù)并排序 int[] ints = { 5, 2, 0, 66, 4, 32, 7, 1 }; // 定義一個(gè)整數(shù)類型的集合,用來存放數(shù)組中的偶數(shù) List<int> list = new List<int>(); // 遍歷數(shù)組查詢出偶數(shù)放到集合中 foreach (int i in ints) { // 如果是偶數(shù),把偶數(shù)加入到集合中 if (i % 2 == 0) { list.Add(i); } }
// 正序排序 list.Sort(); // 反轉(zhuǎn) list.Reverse(); // 輸出 Console.WriteLine(string.Join(",",list));
Console.ReadKey(); } } } 使用for循環(huán)很麻煩,而且不可維護(hù)和可讀。C#2.0引入了delegate,可以使用委托來處理這種場(chǎng)景,代碼如下圖所示: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;
namespace LinqOfSelectOperation { // 定義委托 delegate bool FindEven(int item);
class IntExtension { public static int[] where(int[] array, FindEven dele) { int[] result=new int[5]; int i = 0; foreach (int item in array) { if (dele(item)) { result[i]=item; i++; } }
return result; } } class Program { static void Main(string[] args) { // 查詢出數(shù)組中的偶數(shù)并排序 int[] ints = { 5, 2, 0, 66, 4, 32, 7, 1 };
//delegate(int item){return item % 2 == 0;}表示委托的實(shí)現(xiàn) List<int> list = IntExtension.where(ints, delegate(int item) { return item % 2 == 0; }).ToList(); // 正序排序 list.Sort(); // 反轉(zhuǎn) list.Reverse(); // 輸出 Console.WriteLine(string.Join(",", list));
Console.ReadKey(); } } } 所以,有了C#2.0,通過使用委托有了代理的優(yōu)勢(shì),不必使用for循環(huán)來查詢不同條件的數(shù)組。例如你可以使用相同的委托來查找數(shù)組中的奇數(shù),并降序排序輸出,代碼如下圖所示: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;
namespace LinqOfSelectOperation { // 定義委托 delegate bool FindEven(int item);
class IntExtension { public static int[] where(int[] array, FindEven dele) { int[] result=new int[3]; int i = 0; foreach (int item in array) { if (dele(item)) { result[i]=item; i++; } }
return result; } } class Program { static void Main(string[] args) { // 查詢出數(shù)組中的奇數(shù)并排序 int[] ints = { 5, 2, 0, 66, 4, 32, 7, 1 };
//delegate(int item){return item % 2 != 0;}表示委托的實(shí)現(xiàn) List<int> list = IntExtension.where(ints, delegate(int item) { return item % 2 != 0; }).ToList(); // 正序排序 list.Sort(); // 反轉(zhuǎn) list.Reverse(); // 輸出 Console.WriteLine(string.Join(",", list));
Console.ReadKey(); } } } 雖然使用delegate可以使程序的可讀性增加了,但是C#團(tuán)隊(duì)認(rèn)為他們?nèi)匀恍枰勾a更加緊湊和可讀,所以他們?cè)贑#3.0中引入了擴(kuò)展方法、Lambda表達(dá)式、匿名類型等新特性,你可以使用C#3.0的這些新特性,這些新特性的使用LINQ的前提,可以用來查詢不同類型的集合,并返回需要的結(jié)果。 下面的示例演示了如何使用LINQ和Lambda表達(dá)式根據(jù)特定條件來查詢數(shù)組,示例代碼如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;
namespace LinqOfSelectOperation { class Program { static void Main(string[] args) { // 查詢出數(shù)組中的奇數(shù)并排序 int[] ints = { 5, 2, 0, 66, 4, 32, 7, 1 };
// 使用LINQ和Lambda表達(dá)式查詢數(shù)組中的偶數(shù) int[] intEvens= ints.Where(p => p % 2 == 0).ToArray(); // 使用LINQ和Lambda表達(dá)式查詢數(shù)組中的奇數(shù) int[] intOdds = ints.Where(p => p % 2 != 0).ToArray();
// 輸出 Console.WriteLine("偶數(shù):" + string.Join(",", intEvens)); Console.WriteLine("奇數(shù):" + string.Join(",", intOdds));
Console.ReadKey(); } } } 在上面的例子中可以看到,我們?cè)趩蝹€(gè)語句中使用LINQ和Lambda表達(dá)式指定不同的查詢條件,因此,LINQ使代碼更加緊湊和可讀,并且它也可以用于查詢不同的數(shù)據(jù)源。看到這里的時(shí)候,你可能會(huì)問:究竟什么是LINQ呢?下面將會(huì)具體講解什么是LINQ。 二、什么是LINQ 長期以來,開發(fā)社區(qū)形成以下的格局: 1、面向?qū)ο笈c數(shù)據(jù)訪問兩個(gè)領(lǐng)域長期分裂,各自為政。 2、編程語言中的數(shù)據(jù)類型與數(shù)據(jù)庫中的數(shù)據(jù)類型形成兩套不同的體系,例如: C#中字符串用string數(shù)據(jù)類型表示。 SQL中字符串用NVarchar/Varchar/Char數(shù)據(jù)類型表示。 3、SQL編碼體驗(yàn)落后 沒有智能感知效果。 沒有嚴(yán)格意義上的強(qiáng)類型和類型檢查。 4、SQL和XML都有各自的查詢語言,而對(duì)象沒有自己的查詢語言。 上面描述的問題,都可以使用LINQ解決,那么究竟什么是LINQ呢? LINQ(Language Integrated Query)即語言集成查詢。 LINQ是一組語言特性和API,使得你可以使用統(tǒng)一的方式編寫各種查詢。用于保存和檢索來自不同數(shù)據(jù)源的數(shù)據(jù),從而消除了編程語言和數(shù)據(jù)庫之間的不匹配,以及為不同類型的數(shù)據(jù)源提供單個(gè)查詢接口。 LINQ總是使用對(duì)象,因此你可以使用相同的查詢語法來查詢和轉(zhuǎn)換XML、對(duì)象集合、SQL數(shù)據(jù)庫、ADO.NET數(shù)據(jù)集以及任何其他可用的LINQ提供程序格式的數(shù)據(jù)。 LINQ主要包含以下三部分: 1、LINQ to Objects 主要負(fù)責(zé)對(duì)象的查詢。 2、LINQ to XML 主要負(fù)責(zé)XML的查詢。 3、LINQ to ADO.NET 主要負(fù)責(zé)數(shù)據(jù)庫的查詢。 LINQ to SQL LINQ to DataSet LINQ to Entities 三、LINQ的優(yōu)勢(shì) 1、熟悉的語言:開發(fā)人員不必為每種類型的數(shù)據(jù)源或數(shù)據(jù)格式學(xué)習(xí)新的語言。 2、更少的編碼:相比較傳統(tǒng)的方式,LINQ減少了要編寫的代碼量。 3、可讀性強(qiáng):LINQ增加了代碼的可讀性,因此其他開發(fā)人員可以很輕松地理解和維護(hù)。 4、標(biāo)準(zhǔn)化的查詢方式:可以使用相同的LINQ語法查詢多個(gè)數(shù)據(jù)源。 5、類型檢查:程序會(huì)在編譯的時(shí)候提供類型檢查。 6、智能感知提示:LINQ為通用集合提供智能感知提示。 7、整形數(shù)據(jù):LINQ可以檢索不同形狀的數(shù)據(jù)。 |
|