跟着AI学习C# Day22

📅 Day 22:LINQ(Language Integrated Query)

✅ 学习目标:

  • 理解什么是 LINQ,及其在 C# 中的作用;
  • 掌握使用 LINQ 查询语法(Query Syntax)方法语法(Method Syntax)
  • 熟悉常用 LINQ 操作符(如 WhereSelectOrderByGroupBy 等);
  • 能够对集合、数组、数据库、XML 进行查询操作;
  • 理解延迟执行和立即执行的区别;
  • 编写一个完整的 LINQ 示例程序,如学生管理系统查询模块;
  • 初步了解 LINQ to SQL / Entity Framework 的应用场景。

🧠 一、什么是 LINQ?

LINQ(Language Integrated Query) 是 C# 提供的一种统一的查询语言,它将数据查询集成到 C# 语言中,使得你可以用类似 SQL 的方式来查询各种数据源(如集合、数据库、XML 等)。

主要优点:

特性 描述
类型安全 在编译时检查错误
可读性强 使用声明式语法,代码更清晰
统一查询模型 支持多种数据源(内存对象、SQL、XML 等)

🔁 二、LINQ 的两种语法风格

1. 查询语法(Query Syntax)------ 类似 SQL

csharp 复制代码
var query = from item in collection
            where item.Property > 10
            select item;

2. 方法语法(Method Syntax)------ 使用 Lambda 表达式

csharp 复制代码
var query = collection.Where(item => item.Property > 10);

✅ 实际上两者是等价的,编译器会把查询语法转换为方法语法。


🧩 三、常见 LINQ 操作符

操作符 功能
Where 过滤元素
Select 投影(映射)
OrderBy / OrderByDescending 排序
ThenBy / ThenByDescending 多字段排序
GroupBy 分组
Join 内连接
GroupJoin 分组连接
Distinct 去重
Skip / Take 分页
First / FirstOrDefault 获取第一个元素
Single / SingleOrDefault 获取唯一元素
Count / Sum / Average / Min / Max 聚合操作

🧱 四、基本 LINQ 示例

csharp 复制代码
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6 };

// 查询语法
var evenNumbersQuery = from n in numbers
                       where n % 2 == 0
                       select n;

// 方法语法
var evenNumbersMethod = numbers.Where(n => n % 2 == 0);

foreach (var num in evenNumbersQuery)
{
    Console.WriteLine(num);
}

🔄 五、延迟执行 vs 立即执行

✅ 延迟执行(Deferred Execution)

大多数 LINQ 操作符不会立即执行,而是等到你遍历结果(如 foreach)时才真正执行。

csharp 复制代码
var query = numbers.Where(n => n > 3); // 此时尚未执行
numbers.Add(10);                        // 修改原集合
foreach (var n in query)               // 此时执行,包含新值
    Console.WriteLine(n);

✅ 立即执行(Immediate Execution)

某些方法会在调用时立即执行并返回结果:

方法 说明
ToList() 返回 List<T>
ToArray() 返回数组
ToDictionary() 返回字典
Count() 返回数量
First() / Last() 获取单个元素

💡 六、LINQ 查询复杂对象示例

csharp 复制代码
class Student
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Score { get; set; }
}

List<Student> students = new List<Student>
{
    new Student { Id = 1, Name = "张三", Score = 85 },
    new Student { Id = 2, Name = "李四", Score = 92 },
    new Student { Id = 3, Name = "王五", Score = 78 },
};

// 查询语法
var topStudents = from s in students
                  where s.Score >= 90
                  orderby s.Name descending
                  select s;

// 方法语法
var topStudentsMethod = students
    .Where(s => s.Score >= 90)
    .OrderByDescending(s => s.Name);

foreach (var student in topStudents)
{
    Console.WriteLine($"{student.Id} - {student.Name} : {student.Score}");
}

🧪 七、分组查询(GroupBy)

csharp 复制代码
var grouped = from s in students
              group s by s.Score / 10 into g
              orderby g.Key descending
              select new { Grade = g.Key * 10, Students = g };

foreach (var group in grouped)
{
    Console.WriteLine($"分数段:{group.Grade}-{group.Grade + 9}");
    foreach (var student in group.Students)
    {
        Console.WriteLine("  " + student.Name);
    }
}

🔗 八、LINQ Join 示例(内连接)

csharp 复制代码
class Order
{
    public int Id { get; set; }
    public int StudentId { get; set; }
    public decimal Amount { get; set; }
}

List<Order> orders = new List<Order>
{
    new Order { Id = 1, StudentId = 1, Amount = 100 },
    new Order { Id = 2, StudentId = 2, Amount = 200 },
};

// 查询语法
var query = from s in students
            join o in orders on s.Id equals o.StudentId
            select new { s.Name, o.Amount };

// 方法语法
var method = students.Join(
    orders,
    s => s.Id,
    o => o.StudentId,
    (s, o) => new { s.Name, o.Amount });

foreach (var item in query)
{
    Console.WriteLine($"{item.Name} - {item.Amount}");
}

🧮 九、聚合函数(Aggregation)

csharp 复制代码
int count = students.Count();
decimal total = orders.Sum(o => o.Amount);
decimal average = orders.Average(o => o.Amount);
Student topStudent = students.OrderByDescending(s => s.Score).First();

📝 十、LINQ to Objects、LINQ to SQL、LINQ to XML

LINQ 类型 数据源 用途
LINQ to Objects 集合、数组 内存中查询
LINQ to SQL SQL Server 数据库 简单 ORM
LINQ to Entities Entity Framework ORM 扩展
LINQ to XML XML 文档 XML 解析/生成

💪 实战练习:学生信息查询系统

功能要求:

  • 定义 Student 类,包含姓名、年龄、成绩;
  • 创建多个学生对象;
  • 实现以下功能:
    • 查询所有及格的学生;
    • 查询最高分和平均分;
    • 按成绩降序排列输出;
    • 将结果保存为列表或数组。
示例代码:
csharp 复制代码
class Program
{
    static void Main()
    {
        List<Student> students = new List<Student>
        {
            new Student { Name = "张三", Age = 20, Score = 88 },
            new Student { Name = "李四", Age = 22, Score = 95 },
            new Student { Name = "王五", Age = 21, Score = 70 },
            new Student { Name = "赵六", Age = 19, Score = 65 },
        };

        var passed = students.Where(s => s.Score >= 60);
        var topScore = students.Max(s => s.Score);
        var avgScore = students.Average(s => s.Score);
        var sorted = students.OrderByDescending(s => s.Score);

        Console.WriteLine("及格学生:");
        foreach (var s in passed)
        {
            Console.WriteLine($"{s.Name} - {s.Score}");
        }

        Console.WriteLine($"\n最高分:{topScore}");
        Console.WriteLine($"平均分:{avgScore:F2}");

        Console.WriteLine("\n按成绩排序:");
        foreach (var s in sorted)
        {
            Console.WriteLine($"{s.Name} - {s.Score}");
        }
    }
}

class Student
{
    public string Name { get; set; }
    public int Age { get; set; }
    public int Score { get; set; }
}

📝 小结

今天你学会了:

  • 什么是 LINQ,它在 C# 中的作用;
  • 掌握了 LINQ 的两种语法风格(查询语法 & 方法语法);
  • 熟悉了常见的 LINQ 操作符(如 Where、Select、OrderBy、GroupBy、Join);
  • 理解了延迟执行与立即执行的区别;
  • 编写了多个 LINQ 示例,包括查询、排序、分组、连接等;
  • 初步了解了 LINQ to SQL 和 LINQ to XML 的应用场景。

LINQ 是现代 C# 开发中不可或缺的工具之一,掌握它可以显著提升你在处理集合、数据库、XML 等数据源时的效率和代码可读性。


🧩 下一步学习方向(Day 23)

明天我们将进入一个新的主题 ------ 表达式树(Expression Trees)与动态查询构建,你将学会如何使用表达式树构建动态 LINQ 查询、实现条件筛选、自定义查询逻辑等高级技巧。