Linq :最終統(tǒng)治了?所有的語言!

LINQ:最終統(tǒng)治了所有的語言!
讓我們看看LINQ如何徹底改變了.NET中訪問數(shù)據(jù)的方式
.NET與其他技術(shù)棧的不同之處之一絕對(duì)是LINQ,它是Language Integrated Query的首字母縮寫。實(shí)際上,它是隨.NET Framework 3.5和Visual Studio 2008引入的,它是第一個(gè)獨(dú)立于體系結(jié)構(gòu)并集成在C#和Visual Basic語言中的框架。
借助LINQ,我們可以使用獨(dú)立于各種源的單個(gè)編程模型來查詢和操作數(shù)據(jù)。為了更好地理解它是什么,我們必須一步步的看下他的發(fā)展歷程。
在C#的第一個(gè)版本中,我們必須使用for或foreach循環(huán)來遍歷一個(gè)集合,正如我們所知,該集合實(shí)現(xiàn)IEnumerable接口,例如,在其中找到一個(gè)特定的對(duì)象。以下代碼返回公司年齡在19至36歲(20至35歲)之間的所有客戶:
class Customer{public int CustomerID { get; set; }public String CustomerName { get; set; }public int Age { get; set; }}class Program{static void Main(string[] args){Customer[] customerArray = {new Customer() { CustomerID = 1, CustomerName = "Joy", Age = 22 },new Customer() { CustomerID = 2, CustomerName = "Bob", Age = 45 },new Customer() { CustomerID = 3, CustomerName = "Curt", Age = 25 },};Customer[] customers = new Customer[10];int i = 0;foreach (Customer cst in customerArray){if (cst.Age > 19 && cst.Age < 36){customers[i] = cst;i++;}}}}
有什么不同的方法?讓我們嘗試從“委托”的概念開始逐步進(jìn)行開發(fā)。delegate和返回的類型的方法的引用類型。它“委托”它旨在執(zhí)行代碼的方法,我們可以用這種方式聲明它:
public delegate bool Operations(int number);此委托可以指向所有接受輸入整數(shù)并返回布爾值的方法。例如,假設(shè)在CustomerOperations類中有一個(gè)方法:
public bool CustomerAgeRangeCheck(int number){return number > 19 && number < 36;}
我們可以注冊(cè)一個(gè)或多個(gè)將在執(zhí)行委托時(shí)執(zhí)行的方法:
Operations op = new Operations(CustomerOperations.CustomerAgeRangeCheck);或者簡(jiǎn)單地:
Operations op = CustomerOperations.CustomerAgeRangeCheck; 因此,我們可以使用委托,在這種情況下,它將返回true:
op(22); 委托用于將方法作為參數(shù)傳遞給其他方法:事件處理程序和回調(diào)是通過委托調(diào)用的方法的示例。
C#2.0引入了匿名委托,您現(xiàn)在可以使用匿名方法來聲明和初始化委托。例如,我們可以這樣寫:
delegate bool CustomerFilters(Customer customer);class CustomerOperations{public static Customer[] FindWhere(Customer[] customers, CustomerFilters customerFiltersDelegate){int i = 0;Customer[] result = new Customer[6];foreach (Customer customer in customers)if (customerFiltersDelegate(customer)){result[i] = customer;i++;}return result;}}class Program{static void Main(string[] args){Customer[] customers = {new Customer() { CustomerID = 1, CustomerName = "Joy", Age = 22 },new Customer() { CustomerID = 2, CustomerName = "Bob", Age = 45 },new Customer() { CustomerID = 3, CustomerName = "Curt", Age = 25 },};Customer[] filteredCustomersAge = CustomerOperations.FindWhere(customers, delegate (Customer customer) //Using anonimous delegate{return customer.Age > 19 && customer.Age < 36;});}}
使用C#2.0,我們的優(yōu)勢(shì)是可以使用匿名委托在不同條件下進(jìn)行搜索,而無需使用for或foreach循環(huán)。例如,我們可以使用上一個(gè)示例中相同的委托函數(shù)來查找“ CustomerID”為3或名稱為“ Bob”的客戶:
Customer[] filteredCustomersId = CustomerOperations.FindWhere(customers, delegate (Customer customer){return customer.CustomerID == 3;});Customer[] filteredCustomersName = CustomerOperations.FindWhere(customers, delegate (Customer customer){return customer.CustomerName == "Bob";});
隨著C#的發(fā)展,從3.x版本開始,Microsoft團(tuán)隊(duì)引入了新功能,使代碼更加緊湊和易讀。這些直接支持LINQ來查詢不同類型的數(shù)據(jù)源并獲得產(chǎn)生單個(gè)指令的元素。
這些功能是:
-在VAR結(jié)構(gòu),一個(gè)隱式類型的局部變量。它是強(qiáng)類型化的,因?yàn)橐呀?jīng)聲明了類型本身,但是由編譯器根據(jù)分配給它的值使用類型推斷來確定類型。以下兩個(gè)語句在功能上等效:
var customerAge = 30; // Implicitly typed.int customerAge = 30; // Explicitly typed.
-使用對(duì)象初始化程序,您可以在對(duì)象創(chuàng)建期間將值分配給對(duì)象的全部或某些屬性,而無需在分配指令行之后調(diào)用構(gòu)造函數(shù)。
Customer customer = new Customer { Age = 30, CustomerName = "Adolfo" };與以下代碼不同,在前一種情況下,所有內(nèi)容都被視為單個(gè)操作。
Customer customer = new Customer();customer.Age = 30;customer.CustomerName = "Adolfo";
匿名類型,由編譯器構(gòu)建的只讀類型,只有編譯器知道它。但是,如果程序集中的兩個(gè)或多個(gè)匿名對(duì)象初始化程序具有相同順序的屬性序列,并且具有相同的名稱和類型,則編譯器會(huì)將這些對(duì)象視為相同類型的實(shí)例。
匿名類型是將查詢結(jié)果中的一組屬性臨時(shí)分組的好方法,而不必定義單獨(dú)的命名類型。?
var customer = new { YearsOfFidelity = 10, Name = "Francesco"}; -擴(kuò)展方法,使您可以將方法“添加”到現(xiàn)有類型,而無需創(chuàng)建新的派生類型,重新編譯或修改原始類型。擴(kuò)展方法是靜態(tài)方法,但由于引入了語法糖,因此被稱為,因?yàn)樗鼈兪菙U(kuò)展類型上的實(shí)例方法。
public static class StringExtensionMethods{public static string ReverseString(this string input){if (string.IsNullOrEmpty(input)) return "";return new string(input.ToCharArray().Reverse().ToArray());}}
擴(kuò)展方法必須在靜態(tài)類中定義。第一個(gè)參數(shù)表示要擴(kuò)展的類型,并且必須以關(guān)鍵字this開頭,其他參數(shù)則不需要它。
Console.WriteLine("Hello".ReverseString()); //olleH請(qǐng)注意,在方法調(diào)用中不得指定第一個(gè)參數(shù),該參數(shù)以this修飾符開頭。
Lambda表達(dá)式,可作為可變的或作為在一方法調(diào)用中的參數(shù)被傳遞匿名函數(shù)。
customer => customer.Age > 19 && customer.Age < 36;=>運(yùn)算符稱為lambda運(yùn)算符,而customer是函數(shù)的輸入?yún)?shù)。lambda運(yùn)算符右側(cè)的部分代表函數(shù)的主體及其返回的值,在這種情況下為布爾值。
在LINQ的引入中,我們終于有了C#3.5版本。
簡(jiǎn)而言之,我們可以說LINQ是IEnumerable?
我們有幾種可用的LINQ實(shí)現(xiàn):
?LINQ到對(duì)象(內(nèi)存中對(duì)象集合)?LINQ到實(shí)體(實(shí)體框架)?LINQ to SQL(SQL數(shù)據(jù)庫)?LINQ to XML(XML文檔)?LINQ到數(shù)據(jù)集(ADO.Net數(shù)據(jù)集)?通過實(shí)現(xiàn)IQueryable接口(其他數(shù)據(jù)源)
在前面的示例中,數(shù)組用作數(shù)據(jù)源,因此隱式支持通用接口IEnumerable
正如我們所說,LINQ查詢主要基于.NET Framework 2.0版中引入的通用類型。這意味著,例如,如果嘗試將Customer對(duì)象添加到List
如果愿意,可以使用前面提到的var關(guān)鍵字來避免通用語法,在下面的示例中,該關(guān)鍵字要求編譯器通過檢查from子句中指定的數(shù)據(jù)源來推斷查詢變量的類型。
因此,讓我們看看如何能達(dá)到同樣的效果,在前面的代碼中我們獲得了使用匿名委托,使用LINQ到對(duì)象查詢,該變種構(gòu)造和lambda表達(dá)式:
var filteredCustomersAge = customers.Where(c => c.Age > 19 && c.Age < 36);這種語法稱為方法語法。
在下一個(gè)示例中,我們將使用查詢語法(Query Syntax),該語法是為那些已經(jīng)了解SQL語言并且因此會(huì)喜歡這種方法的人引入的:
var filteredCustomersAge =from customer in customerswhere customer.Age > 19 && customer.Age < 36select customer;
查詢語法和方法語法在語義上是相同的,許多人發(fā)現(xiàn)查詢的語法更簡(jiǎn)單,更易于閱讀 在查詢語法中,LINQ查詢運(yùn)算符在編譯時(shí)轉(zhuǎn)換為對(duì)相關(guān)LINQ擴(kuò)展方法的調(diào)用。
在下一篇文章中,我們將繼續(xù)討論LINQ!
我們將討論IQueryable?
與遠(yuǎn)程數(shù)據(jù)庫一樣,我們還將看到LINQ與內(nèi)存外集合的數(shù)據(jù)源一起使用。


PanDownload復(fù)活了,60MB/s,目前已開源!

臥槽:第一次見這么牛x的網(wǎng)站?
