C# LINQ學習筆記二:LINQ標準查詢操作概述

来源:https://www.cnblogs.com/atomy/archive/2019/12/26/12099096.html
-Advertisement-
Play Games

本筆記摘抄自:https://www.cnblogs.com/liqingwen/p/5801249.html,記錄一下學習過程以備後續查用。 “標準查詢運算符”是組成語言集成查詢 (LINQ) 模式的方法,大多數這些方法都在序列上運行,其中的序列是一個對象,其類型實現了IEnumerable<T> ...


    本筆記摘抄自:https://www.cnblogs.com/liqingwen/p/5801249.html,記錄一下學習過程以備後續查用。

    “標準查詢運算符”是組成語言集成查詢 (LINQ) 模式的方法,大多數這些方法都在序列上運行,其中的序列是一個對象,其類型實現了IEnumerable<T>介面

或 IQueryable<T> 介面。標準查詢運算符提供了包括篩選、投影、聚合、排序等功能在內的查詢功能,各個標準查詢運算符在執行時間上有所不同,具體情況

取決於它們是返回單一值還是值序列:

    返回單一值的方法(例如Average和Sum)會立即執行,返回序列的方法會延遲查詢執行,並返回一個可枚舉的對象。 

    對於在記憶體中集合上運行的方法(即擴展IEnumerable<T>的方法),返回的可枚舉對象將捕獲傳遞到方法的參數。在枚舉該對象時,將使用查詢運算符的

邏輯,並返回查詢結果。與之相反,擴展IQueryable<T>的方法不會實現任何查詢行為,但會生成一個表示要執行的查詢的表達式樹,查詢處理由源

IQueryable<T>對象處理。

    一、按標準執行方式分類

    標準查詢運算符方法的LINQ to Objects實現採用兩種主要方式之一來執行:立即執行和延遲執行,採用延遲執行的查詢運算符可以進一步分為兩類:流式和

非流式。

    1、執行方式

    立即執行:立即執行意味著在代碼中聲明查詢的位置讀取數據源並執行運算,返回單個不可枚舉的結果的所有標準查詢運算符都立即執行。

    延遲執行:延遲執行意味著不在代碼中聲明查詢的位置執行運算,僅當對查詢變數進行枚舉操作時才執行運算,例如通過使用foreach語句,這意味著查詢的

執行結果取決於執行查詢而非定義查詢時的數據源內容。如果多次枚舉查詢變數,則每次結果可能都不同。幾乎所有返回類型為IEnumerable<T>或

IOrderedEnumerable<TElement>的標準查詢運算符都以延遲方式執行。

    2、延遲執行

    流式:運算符不需要在生成元素前讀取所有源數據。在執行時,流式運算符一邊讀取每個源元素,一邊對該源元素執行運算,併在可行時生成元素,流式運

算符將持續讀取源元素直到可以生成結果元素,這意味著可能要讀取多個源元素才能生成一個結果元素。

    非流式:運算符必須讀取所有源數據才能生成結果元素,諸如排序和分組等運算屬於此類別。在執行時,非流式查詢運算符讀取所有源數據,將其放入數據

結構中,執行運算然後生成結果元素。

    二、排列數據

    排序操作按一個或多個特性對序列的元素進行排序。第一個排序條件對元素執行主要排序,通過指定第二個排序條件,可以對各個主要排序組中的元素進行

排序。
    下圖演示對一個字元序列按字母排序操作的執行結果 :

標準查詢運算符操作方法 - 排序
方法名 說明 C# 查詢表達式語法
OrderBy 按升序對值進行排序。 orderby
OrderByDescending 按降序對值進行排序。 orderby … descending
ThenBy 按升序執行次要排序。 orderby …, …
ThenByDescending 按降序執行次要排序。 orderby …, … descending
Reverse 顛倒集合中的元素的順序。 X

    下麵代碼演示orderby升序排序:

    class Program
    {
        static void Main(string[] args)
        {
            #region LINQ orderby升序排序
            var words = new[] { "the", "quick", "brown", "fox", "jumps" };
            var query = 
                from word in words
                orderby word.Length
                select word;
            foreach (var word in query)
            {
                Console.WriteLine(word);
            }
            Console.Read();
            #endregion
        }
    }
View Code

    運行結果如下:

    下麵代碼演示orderby降序排序:

    class Program
    {
        static void Main(string[] args)
        {
            #region LINQ orderby降序排序
            var words = new[] { "the", "quick", "brown", "fox", "jumps" };
            var query = 
                from word in words
                orderby word.Substring(0, 1) descending
                select word;
            foreach (var word in query)
            {
                Console.WriteLine(word);
            }
            Console.Read();
            #endregion
        }
    }
View Code

    運行結果如下:

    下麵代碼演示orderby主要和次要排序(示例一):

    class Program
    {
        static void Main(string[] args)
        {
            #region LINQ orderby主要和次要排序示例一
            var words = new[] { "the", "quick", "brown", "fox", "jumps" };
            var query = 
                from word in words
                orderby word.Length, word.Substring(0, 1)
                select word;
            foreach (var word in query)
            {
                Console.WriteLine(word);
            }
            Console.Read();
            #endregion
        }
    }
View Code

    運行結果如下:

    下麵代碼演示orderby主要和次要排序(示例二):

    class Program
    {
        static void Main(string[] args)
        {
            #region LINQ orderby主要和次要排序示例二
            var words = new[] { "the", "quick", "brown", "fox", "jumps" };
            var query = 
                from word in words
                orderby word.Length, word.Substring(0, 1) descending
                select word;
            foreach (var word in query)
            {
                Console.WriteLine(word);
            }
            Console.Read();
            #endregion
        }
    }
View Code

    運行結果如下:

    三、Set 操作

    LINQ中的Set操作是指根據相同或不同集合中是否存在等效元素來生成結果集的查詢操作。

標準查詢運算符操作方法 - Set
方法名 說明

C# 查詢表達式語法

Distinct

從集合移除重覆值。

X

Except

返回差集,差集是指位於一個集合但不位於另一個集合的元素。

X

Intersect

返回交集,交集是指同時出現在兩個集合中的元素。

X

Union

返回並集,並集是指位於兩個集合中任一集合的唯一的元素。

X

    圖解Set操作

    1、Distinct: 返回的序列包含輸入序列的唯一元素。

    2、Except: 返回的序列只包含位於第一個輸入序列但不位於第二個輸入序列的元素。

    3、Intersect: 返回的序列包含兩個輸入序列共有的元素。

    4、Union: 返回的序列包含兩個輸入序列的唯一的元素。

    四、過濾數據

    篩選指將結果集限製為只包含某些滿足指定條件的元素的操作,它又稱為選擇。

    下圖演示了對字元序列進行篩選的結果,篩選操作的謂詞指定字元必須為“A”。

標準查詢運算符操作方法 - 篩選
方法名 說明 C# 查詢表達式語法
OfType 根據值強制轉換為指定類型的能力選擇值。 X
Where 選擇基於謂詞函數的值。 where

    下麵代碼演示過濾數據:

    class Program
    {
        static void Main(string[] args)
        {
            #region LINQ 過濾數據
            string[] words = { "the", "quick", "brown", "fox", "jumps" };
            var query = 
                from word in words
                where word.Length == 3
                select word;
            foreach (var word in query)
            {
                Console.WriteLine(word);
            }
            Console.Read();
            #endregion
        }
    }
View Code

    運行結果如下:

    五、量詞操作

    限定符運算返回一個Boolean值,該值指示序列中是否有一些元素滿足條件或是否所有元素都滿足條件。

    下圖描述了兩個不同源序列上的兩個不同限定符運算。第一個運算詢問是否有一個或多個元素為字元“A”,結果為true,第二個運算詢問是否所有元素都為字

符“A”,結果為true。

標準查詢運算符操作方法 - 量詞

方法名

說明

C# 查詢表達式語法

All

確定是否序列中的所有元素都滿足條件。

X
Any

確定序列中是否有元素滿足條件。

X

Contains

確定序列是否包含指定的元素。

X

    六、投影操作

    投影是指將對象轉換為一種新形式的操作,該形式通常只包含那些將隨後使用的屬性。通過使用投影,您可以構建依據每個對象生成的新類型,還可以映射

屬性,並對該屬性執行數學函數,另外還可以在不更改原始對象的情況下映射該對象。

標準查詢運算符操作方法 - 投影
方法名 說明 C# 查詢表達式語法
Select 映射基於轉換函數的值。 select
SelectMany 映射基於轉換函數的值序列,然後將它們展平為一個序列。 使用多個 from 子句

    下麵代碼演示Select:

    class Program
    {
        static void Main(string[] args)
        {
            #region LINQ Select
            var words = new[] { "the", "quick", "brown", "fox", "jumps" };
            var query = 
                from word in words
                select word.Substring(0, 1);
            foreach (var word in query)
            {
                Console.WriteLine(word);
            }
            Console.Read();
            #endregion
        }
    }
View Code

    運行結果如下:

    下麵代碼演示SelectMany:

    class Program
    {
        static void Main(string[] args)
        {
            #region LINQ SelectMany
            var phrases = new List<string>() { "an apple a day", "the quick brown fox" };
            var query = 
                from phrase in phrases
                    from word in phrase.Split(' ')
                    select word;
            foreach (var word in query)
            {
                Console.WriteLine(word);
            }
            Console.Read();
            #endregion
        }
    }
View Code

    運行結果如下:

    Select()SelectMany()的工作都是依據源值生成一個或多個結果值。Select()為每個源值生成一個結果值。因此,總體結果是一個與源集合具有相同元素數

目的集合。與之相反,SelectMany()將生成單一總體結果,其中包含來自每個源值的串聯子集合。作為參數傳遞到SelectMany()的轉換函數必須為每個源值返

回一個可枚舉值序列,然後,SelectMany() 將串聯這些可枚舉序列以創建一個大的序列。

    下麵兩個插圖演示了這兩個方法的操作之間的概念性區別。在每種情況下,假定選擇器(轉換)函數從每個源值中選擇一個由花卉數據組成的數組。

    下圖描述 Select() 如何返回一個與源集合具有相同元素數目的集合。

    下圖描述SelectMany()如何將中間數組序列串聯為一個最終結果值,其中包含每個中間數組中的每個值。

    下麵的示例比較Select()SelectMany()的行為。代碼將通過從源集合的每個花卉名稱列表中提取前兩項來創建一個“花束”。在此示例中,轉換函數Select使用

的“單一值”本身就是一個值集合。這需要額外的foreach迴圈,以便枚舉每個子序列中的每個字元串。

    /// <summary>
    /// 花束類
    /// </summary>
    class Bouquet
    {
        public List<string> Flowers { get; set; }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            #region LINQ Select和SelectMany比較
            var bouquets = new List<Bouquet>()
            {
                new Bouquet {Flowers = new List<string> {"sunflower", "daisy", "daffodil", "larkspur"}},
                new Bouquet {Flowers = new List<string> {"tulip", "rose", "orchid"}},
                new Bouquet {Flowers = new List<string> {"gladiolis", "lily", "snapdragon", "aster", "protea"}},
                new Bouquet {Flowers = new List<string> {"larkspur", "lilac", "iris", "dahlia"}}
            };

            IEnumerable<List<string>> query1 = bouquets.Select(bq => bq.Flowers);
            IEnumerable<string> query2 = bouquets.SelectMany(bq => bq.Flowers);

            Console.WriteLine("query1->Select():");
            foreach (IEnumerable<string> collection in query1)
            {
                foreach (var item in collection)
                {
                    Console.WriteLine(item);
                }
            }

            Console.WriteLine("\nquery2->SelectMany():");
            foreach (var item in query2)
            {
                Console.WriteLine(item);
            }

            Console.Read();
            #endregion
        }
    }
View Code

    運行結果如下:

    七、劃分數據

    LINQ 中的分區指的是在不重新排列元素的情況下,將輸入序列劃分為兩部分,然後返回其中一個部分的操作。

    下圖顯示對一個字元序列執行三個不同的分區操作的結果。第一個操作返回序列中的前三個元素;第二個操作跳過前三個元素,返回剩餘的元素;第三個操作

跳過序列中的前兩個元素,返回接下來的三個元素。

分區序列的標準查詢運算符方法

運算符名稱

說明

C# 查詢表達式語法

Skip

跳過序列中的指定位置之前的元素。

X

SkipWhile

基於謂詞函數跳過元素,直到某元素不再滿足條件。

X

Take

提取序列中的指定位置之前的元素。

X

TakeWhile

基於謂詞函數提取元素,直到某元素不再滿足條件。 X

    八、聯接操作

    將兩個數據源“聯接”就是將一個數據源中的對象與另一個數據源中共用某個通用特性的對象關聯起來。

    當查詢所面向的數據源相互之間具有無法直接領會的關係時,聯接就成為一項重要的運算。在面向對象的編程中,這可能意味著在未建模對象之間進行關聯,

例如對單向關係進行反向推理。

    LINQ 框架中提供的聯接方法包括JoinGroupJoin。這些方法執行同等聯接,即根據兩個數據源的鍵是否相等來匹配這兩個數據源的聯接。(與此相較,

Transact-SQL支持除“等於”之外的聯接運算符,例如“小於”運算符。)用關係資料庫術語表達,就是說Join實現了內部聯接,這種聯接只返回那些在另一個數據集

中具有匹配項的對象。GroupJoin方法在關係資料庫術語中沒有直接的等效項,但它實現了內部聯接和左外部聯接的超集。左外部聯接是這樣一種聯接:它返回第

一個(左)數據源的每個元素,即使該元素在另一個數據源中沒有關聯元素。

    下圖顯示了一個概念性視圖,其中包含兩個集合以及這兩個集合中的包含在內部聯接或左外部聯接中的元素。

標準查詢運算符操作方法 - 聯接

方法名

描述

C# 查詢表達式語法

Join

根據鍵選擇器函數聯接兩個序列並提取值對。

join … in … on … equals …

GroupJoin

根據鍵選擇器函數聯接兩個序列,並對每個元素的結果匹配項進行分組。

join … in … on … equals … into …

    九、分組數據

    分組指將數據放入組中以便每個組中的元素共用公共特性的操作。

    下圖顯示了對字元序列進行分組的結果,每個組的鍵是字元。

標準查詢運算符方法 - 分組

方法名

說明

C# 查詢表達式語法

GroupBy

對共用公共特性的元素進行分組。  每個組都由一個 IGrouping<TKey, TElement> 對象表示。  

group … by 

- 或 -

group … by … into …

ToLookup

根據鍵選擇器函數將元素插入到 Lookup<TKey, TElement>(一個一對多字典)中。

X

    下麵代碼演示分組數據:

    class Program
    {
        static void Main(string[] args)
        {
            #region LINQ 分組數據
            var numbers = new List<int>() { 35, 44, 200, 84, 3987, 4, 199, 329, 446, 208 };
            IEnumerable<IGrouping<bool, int>> query = from number in numbers
                                                      group number by number % 2 == 0;
            foreach (var group in query)
            {
                Console.WriteLine($"{(group.Key ? "偶數" : "基數")}:");
                foreach (var item in group)
                {
                    Console.WriteLine(item);
                }
            }
            Console.Read();
            #endregion
        }
    }
View Code

    運行結果如下:

    十、生成操作

    生成是指創建新的值序列。

標準查詢運算符方法 - 生成

方法名

說明

C# 查詢表達式語法

DefaultIfEmpty

將空集合替換為具有預設值的單一實例集合。

X
Empty

返回空集合。

X
Range

生成包含數字序列的集合。

X

Repeat

生成包含一個重覆值的集合。

X

    十一、等值操作

    如果兩個序列的對應元素相等且這兩個序列具有相同數量的元素,則視這兩個序列相等。

標準查詢運算符方法 - 等值
方法名 說明 C# 查詢表達式語法
SequenceEqual 通過成對地比較元素確定兩個序列是否相等。 X

    十二、元素操作

    元素操作從一個序列返回單個特定元素。

標準查詢運算符操作方法 - 元素 

方法名

說明

C# 查詢表達式語法

ElementAt

返回集合中指定索引處的元素。

X

ElementAtOrDefault

返回集合中指定索引處的元素;如果索引超出範圍,則返回預設值。

X

First

返回集合中的第一個元素或滿足條件的第一個元素。

X

FirstOrDefault

返回集合中的第一個元素或滿足條件的第一個元素。如果沒有這樣的元素,則返回預設值。  

X
Last

返回集合中的最後一個元素或滿足條件的最後一個元素。

X

LastOrDefault

返回集合中的最後一個元素或滿足條件的最後一個元素。如果沒有這樣的元素,則返回預設值。  

X

Single

返回集合中的唯一元素或滿足條件的唯一元素。

X

SingleOrDefault

返回集合中的唯一元素或滿足條件的唯一元素。如果沒有這樣的元素或集合不是正好包含一個元素,則返回預設值。  

X

    十三、轉換數據類型 

    轉換方法更改輸入對象的類型。

    LINQ查詢中的轉換運算可用於各種應用程式,下麵是一些示例:

    1、Enumerable.AsEnumerable<TSource> 方法可用於隱藏類型的標準查詢運算符的自定義實現。

    2、Enumerable.OfType<TResult> 方法可用於啟用非參數化集合以進行LINQ查詢。

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 簡介 Min_25篩~~據說~~可以在$O(\frac{n^{\frac{3}{4}}}{logn})$處理出含有以下性質的函數f的首碼和: 1.$f(ab)=f(a)f(b)$,即f是一個積性函數 2.$f(p^k)$可以快速計算。 PS:本文沒有關於複雜度的證明。。。 預處理 首先要預處理兩個東 ...
  • springboot集成開發實現商場秒殺 加入主要依賴 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependen ...
  • "題目鏈接" problem 給出一個$n,n include include include include include include include include using namespace std; typedef long long ll; const int N = 50001 ...
  • 場景 Dubbo環境搭建-管理控制台dubbo-admin實現服務監控: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/103624846 Dubbo搭建HelloWorld-搭建服務提供者與服務消費者並完成遠程調用(附代碼下載) ...
  • 這篇文章介紹的內容是關於PHP+Mysql防止SQL註入的方法,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下 方法一: mysql_real_escape_string -- 轉義 SQL 語句中使用的字元串中的特殊字元,並考慮到連接的當前字元集 ! $sql = "select c ...
  • 本篇文章給大家分享的內容是關於如何通過Docker搭建一個swoft開發環境 ,內容很詳細,有需要的朋友可以參考一下,希望可以幫助到你們。Swoft首個基於 Swoole 原生協程的新時代 PHP 高性能協程全棧組件化框架,內置協程網路伺服器及常用的協程客戶端,常駐記憶體,不依賴傳統的 PHP-FPM ...
  • 在項目中經常用到枚舉作為數據字典值和描述的相互轉化。 用法如下: 當枚舉類多了之後,會存在很多重覆的值和描述相互轉化的方法,類似getEnmuByValue和getEnmuByKey。 最近找到一種方法,利用介面、介面預設方法、泛型,實現通用的方法。同類型的枚舉只需要實現該介面即可。 代碼如下: 具 ...
  • 最近項目涉及到一個定時任務的功能,所以去這幾天研究了一下 crontab 的使用方法,按照網上的相關教程順利在自己的電腦上成功開啟了這個功能 Laravel + crontab 添加 crontab 配置 1、執行命令 $ crontab -e 2、添加以下內容( path/to為應用路徑 ),即每 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...