文章

第14天:LINQ 基礎

課程簡介

今天,我們將探討 C# 中的 LINQ(Language Integrated Query),這是一組語法功能,使您能夠對集合、數據庫、XML 等各種資料來源執行查詢操作。LINQ 讓您能夠使用直觀的方式來篩選、排序、分組和投影資料。它與 Lambda 表達式緊密結合,使代碼更簡潔、易讀且功能強大。


學習目標

  • 理解 LINQ 的基本概念和用法
  • 探索 LINQ 的查詢語法和方法語法
  • 學會使用 LINQ 查詢篩選、排序、分組和投影資料
  • 實作 LINQ 基礎操作以便輕鬆處理集合資料

課程內容

1. LINQ 概念介紹

LINQ 提供了兩種常見的語法:查詢語法方法語法

  • 查詢語法:類似於 SQL 語句的語法,使用關鍵字來執行查詢。
  • 方法語法:基於 Lambda 表達式和方法的鏈式操作,用來篩選、排序、分組等。

LINQ 支援操作不同的資料來源,如 ListArrayDictionary,甚至是資料庫中的資料。


2. LINQ 查詢語法

查詢語法讓您可以用類似 SQL 的方式來查詢資料集合。它適用於所有支援 IEnumerable<T>IQueryable<T> 的集合。

基本語法:

1
2
3
var result = from element in collection
             where condition
             select element;

範例:

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

var evenNumbers = from num in numbers
                  where num % 2 == 0
                  select num;

foreach (var number in evenNumbers)
{
    Console.WriteLine(number);  // 輸出 2, 4, 6, 8, 10
}

此查詢中,我們使用 from 來遍歷集合中的每個元素,接著使用 where 子句篩選出偶數,最後用 select 返回結果。


3. LINQ 方法語法

方法語法使用 Lambda 表達式,能讓您以更具可讀性的方式鏈接多個操作。

常用方法:

  • Where:篩選符合條件的元素。
  • OrderByOrderByDescending:對結果排序。
  • Select:投影集合中的元素。
  • GroupBy:分組元素。
  • FirstFirstOrDefault:返回集合中第一個符合條件的元素。

範例:

1
2
3
4
5
6
7
8
9
10
List<string> names = new List<string> { "Alice", "Bob", "Charlie", "David" };

// 使用方法語法篩選名字長度大於 3 的項目,並進行排序
var filteredNames = names.Where(name => name.Length > 3)
                         .OrderBy(name => name);

foreach (var name in filteredNames)
{
    Console.WriteLine(name);  // 輸出 "Alice", "Charlie", "David"
}

在此範例中,我們使用了 WhereOrderBy 方法進行篩選和排序,代碼直觀且簡潔。


4. LINQ 查詢的常用操作

LINQ 提供了許多強大的操作來處理集合資料。以下是一些常見的操作及其示例:

a. 篩選 - Where

Where 方法用於篩選符合條件的項目:

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

var smallNumbers = numbers.Where(n => n < 4);

foreach (var number in smallNumbers)
{
    Console.WriteLine(number);  // 輸出 1, 2, 3
}

b. 投影 - Select

Select 方法用於投影集合中的元素,通常用於從集合中選取特定屬性或進行運算。

1
2
3
4
5
6
7
8
string[] fruits = { "apple", "banana", "cherry" };

var fruitLengths = fruits.Select(fruit => fruit.Length);

foreach (var length in fruitLengths)
{
    Console.WriteLine(length);  // 輸出 5, 6, 6
}

c. 排序 - OrderByOrderByDescending

這些方法用於對集合進行排序:

1
2
3
4
5
6
7
8
List<int> numbers = new List<int> { 5, 1, 3, 4, 2 };

var sortedNumbers = numbers.OrderBy(n => n);

foreach (var number in sortedNumbers)
{
    Console.WriteLine(number);  // 輸出 1, 2, 3, 4, 5
}

d. 分組 - GroupBy

GroupBy 用於將集合中的元素依照某個屬性或條件分組:

1
2
3
4
5
6
7
8
9
10
11
12
string[] words = { "apple", "banana", "cherry", "avocado" };

var groupedWords = words.GroupBy(word => word[0]);

foreach (var group in groupedWords)
{
    Console.WriteLine("Words that start with " + group.Key + ":");
    foreach (var word in group)
    {
        Console.WriteLine(word);
    }
}

此範例中,GroupBy 方法根據每個單字的第一個字母進行分組。


5. 查詢的結合操作

LINQ 支援查詢的多重操作,您可以使用 WhereSelectOrderBy 等方法鏈式操作:

1
2
3
4
5
6
7
8
9
10
List<int> numbers = new List<int> { 10, 20, 30, 40, 50 };

var result = numbers.Where(n => n > 20)
                    .OrderByDescending(n => n)
                    .Select(n => n * 2);

foreach (var number in result)
{
    Console.WriteLine(number);  // 輸出 100, 80, 60
}

此範例中,我們先篩選出大於 20 的數字,接著以降序排序,再將結果乘以 2。


實作練習

  1. 篩選出含有字母 ‘a’ 的單字
    • 使用 Where 來篩選出包含字母 ‘a’ 的單字。
    1
    2
    3
    4
    5
    6
    7
    
    string[] words = { "apple", "banana", "cherry", "date" };
    var wordsWithA = words.Where(word => word.Contains("a"));
    
    foreach (var word in wordsWithA)
    {
        Console.WriteLine(word);  // 輸出 "apple", "banana", "date"
    }
    
  2. 計算每個名字的字母數量
    • 使用 Select 計算名字中的字母數量並輸出結果。
    1
    2
    3
    4
    5
    6
    7
    
    List<string> names = new List<string> { "Alice", "Bob", "Charlie" };
    var nameLengths = names.Select(name => new { Name = name, Length = name.Length });
    
    foreach (var item in nameLengths)
    {
        Console.WriteLine(item.Name + " has " + item.Length + " letters.");
    }
    
  3. 將成績列表按照從高到低排序
    • 使用 OrderByDescending 來排序成績列表,並顯示結果。
    1
    2
    3
    4
    5
    6
    7
    8
    
    int[] scores = { 75, 88, 92, 60, 85 };
    var sortedScores = scores.OrderByDescending(score => score);
    
    Console.WriteLine("Sorted scores (high to low):");
    foreach (var score in sortedScores)
    {
        Console.WriteLine(score);  // 輸出 92, 88, 85, 75, 60
    }
    
  4. 將員工依據部門分組
    • 使用 GroupBy 將員工依部門名稱進行分組。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
    var employees = new[]
    {
        new { Name = "Alice", Department = "HR" },
        new { Name = "Bob", Department = "IT" },
        new { Name = "Charlie", Department = "IT" },
        new { Name = "David", Department = "HR" }
    };
    
    var groupedEmployees = employees.GroupBy(emp => emp.Department);
    
    foreach (var group in groupedEmployees)
    {
        Console.WriteLine("Department: " + group.Key);
        foreach (var emp in group)
        {
            Console.WriteLine(emp.Name);
        }
    }
    

教學重點

  • 瞭解 LINQ 的查詢語法和方法語法

  • 學會使用 WhereSelectOrderByGroupBy 等 LINQ 常用方法。
  • 使用 LINQ 進行複合操作來處理集合資料。
  • 掌握 LINQ 在資料篩選、排序和分組上的靈活運用。

在下一節中,我們將探討 LINQ 進階操作,進一步提升處理複雜集合資料的能力。

本文章以 CC BY 4.0 授權