首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# LINQ 查詢語法與方法語法完整入門指南

     編輯:關於C#

Language Integrated Query (LINQ) 是 C# 3.0 引入的革命性特性,提供統一的資料查詢語法。本文涵蓋查詢語法、方法語法、核心運算子、延遲執行機制與實用範例。

兩種語法風格

1. 查詢語法(類 SQL,編譯器轉換為方法呼叫)

var highBmiPeople = from person in people
                    where person.Bmi > 25
                    orderby person.Bmi descending
                    select new { person.Name, person.Bmi };

2. 方法語法(Lambda 表達式,更靈活)

var highBmiPeople = people
    .Where(p => p.Bmi > 25)
    .OrderByDescending(p => p.Bmi)
    .Select(p => new { p.Name, p.Bmi });

核心查詢運算子分類

分類運算子說明
篩選 Where 依條件篩選
OfType<T> 依型別篩選
Take / Skip 取得/略過前 N 筆
Distinct 移除重複
排序 OrderBy / OrderByDescending 主要排序
ThenBy / ThenByDescending 次要排序
Reverse 反轉順序
GroupBy 分組
投影 Select 轉換形狀
SelectMany 扁平化投影
Zip 兩序列合併
Join / GroupJoin 內部/群組聯結
集合 Union / Intersect / Except 聯集/交集/差集
Concat 串連序列
DefaultIfEmpty 空序列預設值
All / Any / Contains 量詞判斷
聚合 Count / Sum / Average / Min / Max 基本聚合
Aggregate 自訂累積
GroupBy + 聚合 分組統計

完整實用範例

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public double Bmi { get; set; }
    public string Department { get; set; }
    public List Skills { get; set; }
}

public class LinqDemo
{
    private List _people = new()
    {
        new Person { Name = "Alice", Age = 28, Bmi = 22.5, Department = "IT", Skills = new() { "C#", "SQL" } },
        new Person { Name = "Bob", Age = 35, Bmi = 27.3, Department = "HR", Skills = new() { "Recruiting" } },
        new Person { Name = "Charlie", Age = 42, Bmi = 31.2, Department = "IT", Skills = new() { "C#", "Azure" } },
        new Person { Name = "Diana", Age = 29, Bmi = 24.8, Department = "Finance", Skills = new() { "Excel", "C#" } },
    };

    public void RunExamples()
    {
        // 1. 篩選 + 投影:BMI > 25 的人名
        var names = _people
            .Where(p => p.Bmi > 25)
            .Select(p => p.Name);
        Console.WriteLine("高 BMI 人員:" + string.Join(", ", names));

        // 2. 分組統計:各部門平均年齡
        var deptAvgAge = _people
            .GroupBy(p => p.Department)
            .Select(g => new { Department = g.Key, AvgAge = g.Average(p => p.Age) });
        foreach (var d in deptAvgAge)
            Console.WriteLine($"{d.Department}: 平均年齡 {d.AvgAge:F1}");

        // 3. 扁平化:所有人的所有技能(去重)
        var allSkills = _people
            .SelectMany(p => p.Skills)
            .Distinct()
            .OrderBy(s => s);
        Console.WriteLine("所有技能:" + string.Join(", ", allSkills));

        // 4. 複雜查詢:IT 部門、年齡 30 以上、依 BMI 降序、取前 2 名
        var topIt = _people
            .Where(p => p.Department == "IT" && p.Age >= 30)
            .OrderByDescending(p => p.Bmi)
            .Take(2)
            .Select(p => $"{p.Name} (BMI: {p.Bmi})");
        Console.WriteLine("資深 IT 高 BMI:" + string.Join(", ", topIt));

        // 5. 聚合:最年長者
        var oldest = _people.OrderByDescending(p => p.Age).First();
        Console.WriteLine($"最年長:{oldest.Name} ({oldest.Age} 歲)");

        // 6. 量詞:是否所有人都會 C#
        bool allKnowCSharp = _people.All(p => p.Skills.Contains("C#"));
        Console.WriteLine($"全員會 C#:{allKnowCSharp}");
    }
}

關鍵概念:延遲執行 vs 立即執行

| 特性 | 延遲執行 | 立即執行 | |------|----------|----------| | 運算子 | Where, Select, OrderBy, GroupBy, Take, Skip | ToList, ToArray, Count, Sum, First, Any | | 執行時機 | 迭代時(foreach、ToList) | 呼叫運算子瞬間 | | 優點 | 可組合、不立即耗資源、支援無限序列 | 確定結果、避免重複查詢、除錯容易 | | 陷阱 | 多次迭代 = 多次查詢、資料可能已變 | 記憶體一次載入全部結果 |
// 延遲執行陷阱範例
var query = people.Where(p => p.Age > 30); // 尚未執行
var count1 = query.Count(); // 執行一次
var count2 = query.Count(); // 再執行一次!

// 修正:具體化
var list = query.ToList();
var count1 = list.Count;
var count2 = list.Count;

進階:查詢語法關鍵字對應

from p in people          // 來源
where p.Age > 30          // Where
orderby p.Name            // OrderBy
group p by p.Dept into g  // GroupBy
select new { g.Key, Count = g.Count() } // Select
join d in depts on p.DeptId equals d.Id // Join
let bmi = p.Weight / (p.Height * p.Height) // 區域變數
into g                    // 群組延續

效能提示

  • 優先使用 IQueryable(EF Core 等)將查詢轉為 SQL 在資料庫端執行
  • 避免在迴圈中重複查詢,先 ToList() 具體化
  • 大量資料考慮 AsParallel()(PLINQ)或分頁 Skip/Take
  • Select 只選需要的欄位,減少資料傳輸
  • 複雜邏輯考慮編譯查詢或原始 SQL

LINQ 不只是語法糖,更是將資料查詢邏輯內建於語言、提供型別安全與智慧提示的強大抽象。熟練掌握 LINQ 將大幅提升 C# 資料處理的開發效率與程式碼品質。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved