LINQ的讲解与示例

时间:2024-10-18 08:27:27

**LINQ 是一种强大的查询语言,可以直接在 C# 中使用,用于查询和操作数据集合。**本篇将在第二阶段的基础上增加对 LINQ(Language Integrated Query)的学习和使用。

文章目录

      • LINQ 知识点讲解
      • 第三阶段:使用 LINQ
        • 1. 增加 LINQ 查询
      • 更新后的代码
        • 1. 基类定义
        • 2. 继承
        • 3. 主程序
      • 解释
      • 总结

LINQ 知识点讲解

  1. 基本概念

    • LINQ:Language Integrated Query 的缩写,是一种在 .NET 中用于查询和操作数据的技术。
    • 查询表达式:使用类似 SQL 的语法来编写查询。
    • 方法语法:使用方法调用来构建查询。
  2. 常用方法

    • Where:用于过滤集合中的元素。
    • Select:用于选择集合中的元素。
    • OrderByOrderByDescending:用于排序集合中的元素。
    • GroupBy:用于对集合中的元素进行分组。
    • First, FirstOrDefault, Single, SingleOrDefault:用于获取集合中的单个元素。
    • Any, All:用于检查集合中的元素是否满足某个条件。
    • Count:用于计算集合中的元素数量。
  3. 延迟执行

    • LINQ 查询通常是延迟执行的,即在查询定义时不会立即执行,而是在遍历结果时才执行。
    • 延迟执行的具体表现
      查询定义:在定义查询时,LINQ 只是创建了一个查询表达式,不会立即执行任何操作。
      查询执行:查询在第一次访问结果时(例如通过 foreach 循环、ToList、ToArray 等方法)才会执行。
      多次执行:每次遍历查询结果时,查询都会重新执行。因此,如果数据源发生变化,查询结果也会相应变化。

第三阶段:使用 LINQ

1. 增加 LINQ 查询

我们将在第二阶段的基础上增加一些 LINQ 查询,以展示如何使用 LINQ 进行数据操作。

更新后的代码

1. 基类定义
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string Gender { get; set; }

    public virtual async Task DisplayInfoAsync()
    {
        Console.WriteLine("Name: {0}", Name);
        Console.WriteLine("Age: {0}", Age);
        Console.WriteLine("Gender: {0}", Gender);
    }
}

public class Course
{
    public string CourseName { get; set; }
    public string CourseCode { get; set; }

    public virtual async Task DisplayInfoAsync()
    {
        Console.WriteLine("Course Name: {0}", CourseName);
        Console.WriteLine("Course Code: {0}", CourseCode);
    }
}
2. 继承
public class Student : Person
{
    public string StudentID { get; set; }
    public List<Course> Courses { get; set; } = new List<Course>();

    public override async Task DisplayInfoAsync()
    {
        await base.DisplayInfoAsync();
        Console.WriteLine("Student ID: {0}", StudentID);
        Console.WriteLine("Courses:");

        foreach (var course in Courses)
        {
            await course.DisplayInfoAsync();
        }
    }

    public async Task LoadCoursesAsync(List<Course> courses)
    {
        // 模拟从网络加载课程数据
        await Task.Delay(1000); // 模拟网络延迟
        Courses.AddRange(courses);
    }

    // 新增 LINQ 查询方法
    public List<Course> GetCoursesByPrefix(string prefix)
    {
        // 使用 LINQ 查询过滤课程名以指定前缀开头的课程
        return Courses.Where(course => course.CourseName.StartsWith(prefix)).ToList();
    }
}

public class Teacher : Person
{
    public string EmployeeID { get; set; }
    public List<Course> Courses { get; set; } = new List<Course>();

    public override async Task DisplayInfoAsync()
    {
        await base.DisplayInfoAsync();
        Console.WriteLine("Employee ID: {0}", EmployeeID);
        Console.WriteLine("Courses:");

        foreach (var course in Courses)
        {
            await course.DisplayInfoAsync();
        }
    }

    public async Task LoadCoursesAsync(List<Course> courses)
    {
        // 模拟从网络加载课程数据
        await Task.Delay(1000); // 模拟网络延迟
        Courses.AddRange(courses);
    }

    // 新增 LINQ 查询方法
    public List<Course> GetCoursesByPrefix(string prefix)
    {
        // 使用 LINQ 查询过滤课程名以指定前缀开头的课程
        return Courses.Where(course => course.CourseName.StartsWith(prefix)).ToList();
    }
}
3. 主程序
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        // 创建课程
        List<Course> courses = new List<Course>
        {
            new Course { CourseName = "Mathematics", CourseCode = "MATH101" },
            new Course { CourseName = "Physics", CourseCode = "PHYS101" },
            new Course { CourseName = "Chemistry", CourseCode = "CHEM101" },
            new Course { CourseName = "Biology", CourseCode = "BIO101" }
        };

        // 创建学生
        Student student1 = new Student
        {
            Name = "Alice",
            Age = 20,
            Gender = "Female",
            StudentID = "S001"
        };

        // 创建教师
        Teacher teacher1 = new Teacher
        {
            Name = "Dr. Smith",
            Age = 35,
            Gender = "Male",
            EmployeeID = "T001"
        };

        // 异步加载课程数据
        await student1.LoadCoursesAsync(courses);
        await teacher1.LoadCoursesAsync(new List<Course> { courses[0], courses[1] });

        // 异步显示学生信息
        Console.WriteLine("Student Information:");
        await student1.DisplayInfoAsync();

        // 异步显示教师信息
        Console.WriteLine("\nTeacher Information:");
        await teacher1.DisplayInfoAsync();

        // 使用 LINQ 查询
        Console.WriteLine("\nCourses for Student with 'Math' prefix:");
        var studentCoursesWithMathPrefix = student1.GetCoursesByPrefix("Math");
        foreach (var course in studentCoursesWithMathPrefix)
        {
            await course.DisplayInfoAsync();
        }

        Console.WriteLine("\nCourses for Teacher with 'Phy' prefix:");
        var teacherCoursesWithPhyPrefix = teacher1.GetCoursesByPrefix("Phy");
        foreach (var course in teacherCoursesWithPhyPrefix)
        {
            await course.DisplayInfoAsync();
        }
    }
}

解释

  1. 新增的 LINQ 查询方法

    • GetCoursesByPrefix 方法:在 StudentTeacher 类中添加了 GetCoursesByPrefix 方法,该方法使用 LINQ 查询来过滤课程名以指定前缀开头的课程。
    • Where 方法:用于过滤集合中的元素,这里用于筛选课程名以指定前缀开头的课程。
    • ToList 方法:将查询结果转换为 List<Course>
  2. 主程序中的 LINQ 使用

    • 在主程序中,我们调用了 GetCoursesByPrefix 方法来获取学生和教师的课程列表中以特定前缀开头的课程,并显示这些课程的信息。

总结

通过在第二阶段的基础上增加 LINQ 查询,展示了如何使用 LINQ 来过滤和操作数据集合。LINQ 提供了一种简洁而强大的方式来处理集合数据,使得代码更加易读和维护。