在本系列博客前面的篇章中,已經(jīng)對(duì)LINQ的作用、C# 3.0為L(zhǎng)INQ提供的新特性,還有幾種典型的LINQ技術(shù):LINQ to Objects、LINQ to SQL、Entity Framework進(jìn)行了比較詳細(xì)的介紹,至此,我們應(yīng)該了解了各種LINQ技術(shù)之間的聯(lián)系和區(qū)別。千里之行始于足下,這些基礎(chǔ)理論是理解和使用LINQ的關(guān)鍵。但是我們?cè)谇懊娴奈恼轮袑?duì)于LINQ查詢運(yùn)算符(LINQ Operators)并沒有完整的介紹,這就是接下來(lái)這幾篇博客中所要做的工作。大家可以按順序依次對(duì)各個(gè)LINQ Operators進(jìn)行學(xué)習(xí),也可以把他們看成一個(gè)reference,作為參考查詢之用。 示例數(shù)據(jù)在這幾篇討論LINQ Operators的文章中,所有的示例都會(huì)(如果需要)用到下面的names數(shù)組: string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" }; 所有查詢數(shù)據(jù)庫(kù)的示例都會(huì)假設(shè)我們創(chuàng)建了強(qiáng)類型的DataCotnext變量dataContext,如下: var dataContext = new LifePoemContext ("connection string..."); 上面的DataContext和實(shí)體類是LINQ to SQL工具(如通過Visual Studio新增一個(gè)”LINQ to SQL Classes” Item)生成的簡(jiǎn)化版本。其中Customer和Purchase包含了一個(gè)簡(jiǎn)單的1:多關(guān)系,下面是對(duì)應(yīng)的SQL表定義: create table Customer Filtering OperatorsIEnumerable<TSource> → IEnumerable<TSource> 返回輸入sequence中元素的一個(gè)子集
對(duì)每一個(gè)過濾方法而言,總是得到一個(gè)少于或等于初始元素個(gè)數(shù)的序列,而不可能返回更多的元素!并且這些元素不會(huì)經(jīng)過任何改變,而是與原始元素一致。 Where
a帶索引的lambda表達(dá)式在LINQ to SQL和Entity Framework中不可用。 查詢表達(dá)式語(yǔ)法:where bool-expression Enumerable.Where實(shí)現(xiàn) Enumerable.Where的內(nèi)部實(shí)現(xiàn)大致如下(略去null引用的檢查): public static IEnumerable<TSource> Where<TSource> 介紹 Where返回輸入sequence中滿足指定條件的elements,比如: string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" }; 對(duì)應(yīng)的查詢表達(dá)式語(yǔ)法: IEnumerable<string> query = from n in names 在一個(gè)查詢中where子句可以出現(xiàn)多次并且可以和let子句搭配使用: string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" }; 索引過濾 Where的條件支持第二個(gè)可選參數(shù),類型為int,它的值等于每個(gè)element在輸入sequence中的位置,這樣我們就可以在lambda表達(dá)式中使用這個(gè)index信息。比如,下面的例子忽略index為單數(shù)的elements: IEnumerable<string> query = names.Where((n, i) => i % 2 == 0); 如果你在LINQ to SQL或Entity Framework中使用索引參數(shù),將會(huì)拋出異常。 LINQ to SQL和EF中的SQL LIKE 比較 下面這些字符串方法會(huì)被翻譯成SQL的LIKE操作符:Contains、StartsWith、EndsWith。 比如:c.Name.Contains ("abc") 翻譯成customer.Name LIKE '?c%' (或者與之等價(jià)的參數(shù)版本)。 需要注意的是,在使用Contains時(shí),我們只能用來(lái)與本地計(jì)算的表達(dá)式進(jìn)行比較,如果要和另外一列進(jìn)行比較,我們必須借助于SqlMethod.Like方法: IQueryable<Purchase> query = purchases LINQ to SQL和EF中的WHERE x IN (..., ..., ...) 對(duì)于LINQ to SQL和EF,我們可以在過濾條件中對(duì)一個(gè)本地集合應(yīng)用Contains方法,比如: string[] chosenOnes = { "Tom", "Jay" }; 這會(huì)映射到SQL的IN操作符,即:WHERE customer.Name IN ("Tom", "Jay")。如果本地集合是一個(gè)entities數(shù)組或其他的非標(biāo)量類型,LINQ to SQL和EF可能會(huì)生成EXISTS子句。 Take和Skips
Take返回前面n個(gè)元素并丟棄剩下的元素;Skip丟棄前面n個(gè)元素并返回剩下的元素。這兩個(gè)方法通常一起使用以實(shí)現(xiàn)web頁(yè)面的數(shù)據(jù)分頁(yè)效果,讓用戶能在一個(gè)大型的結(jié)果集上進(jìn)行導(dǎo)航,比如: // 假設(shè)用戶在一個(gè)圖書數(shù)據(jù)庫(kù)中查找包含"mercury"的所有圖書 對(duì)于SQL Server 2005,LINQ to SQL和EF 會(huì)把Take和Skip翻譯成ROW_NUMBER函數(shù),而對(duì)于更早的SQL Server版本,它們會(huì)被翻譯成Top n子句。 TakeWhile和SkipWhile
TakeWhile遍歷輸入sequence,返回每個(gè)element,直到給定的測(cè)試條件為false,然后忽略剩下的elements: int[] numbers = { 3, 5, 2, 234, 4, 1 }; SkipWhile遍歷輸入sequence,忽略每個(gè)element,直到給定的測(cè)試條件為false,然后返回剩下的elements: int[] numbers = { 3, 5, 2, 234, 4, 1 }; TakeWhile和SkipWhile沒有對(duì)應(yīng)的SQL翻譯,如果在LINQ-to-db查詢中使用他們會(huì)導(dǎo)致運(yùn)行時(shí)錯(cuò)誤。 DistinctDistinct返回去除了重復(fù)元素之后的輸入sequence,在確定元素是否重復(fù)時(shí)只能使用默認(rèn)的相等比較方法: // The following returns distinct letters in a string 我們可以在string變量上直接調(diào)用LINQ方法,因?yàn)閟tring實(shí)現(xiàn)了IEnumerable<char>。 來(lái)源:https://www./content-4-274551.html |
|