C# LINQ 快速入门实战指南,建议收藏学习!

{

                   new Course { CourseID = 101, CourseName = "语文" },
                   new Course { CourseID = 102, CourseName = "数学" }
               }
           }
        };

var listJoin = students.Join(

            otherStudent, // 要连接的第二个集合
            s1 => s1.StudentID, // 从第一个集合中提取键
            s2 => s2.StudentID, // 从第二个集合中提取键
            (s1, s2) => new // 结果选择器,指定如何从两个匹配元素创建结果
            {
                StudentID = s1.StudentID,
                StudentName = s1.StudentName,
                Birthday = s1.Birthday,
                ClassID = s1.ClassID,
                Address = s1.Address,
                Courses = s1.Courses,
                OtherStudentName = s2.StudentName
            });

//使用 GroupJoin 方法实现两个集合的左连接(Left Join)

        //目标:获取所有课程及选修学生(即使无人选修也要显示课程)
        var courseStudentGroups = courses.GroupJoin(
            students.SelectMany(
                student => student.Courses,
                (student, course) => new { Student = student, Course = course }
            ),
            course => course.CourseID,
            studentCoursePair => studentCoursePair.Course.CourseID,
            // 结果投影:生成课程名称及对应的学生列表
            (course, matchedStudents) => new
            {
                CourseName = course.CourseName,
                Students = matchedStudents
                    .Select(pair => pair.Student.StudentName)
                    .DefaultIfEmpty("(无学生)")
                    .ToList()
            }
        ).ToList();

// 输出结果

        foreach (var group in courseStudentGroups)
        {
            Console.WriteLine("-------------------");
            Console.WriteLine($"课程:{group.CourseName}");
            Console.WriteLine($"选修学生:{string.Join(", ", group.Students)}");
            Console.WriteLine("-------------------");
        }
### 跳过与获取指定数量的元素(常用作分页)
- **Skip**:用于跳过集合中指定数量的元素,并返回剩余的元素序列。
- **Take**:用于从集合的开头获取指定数量的元素,并返回一个新的序列。
```csharp
            var skippedStudents = students.Skip(1);
			var takenStudents = students.Take(2);
			//数据分页查询(Skip + Take)
			int pageNumber = 2;
			int pageSize = 10;
			var pagedUsers = skippedStudents
			.OrderBy(u => u.ClassID) // 必须排序
			.Skip((pageNumber - 1) * pageSize).Take(pageSize).ToList();

条件判断方法

  • All:判断集合中的所有元素是否都满足条件。
  • Any:判断集合中是否包含元素或存在元素满足指定条件。
  • Contains:用于判断集合中是否包含指定的元素。
            bool allAdults = students.All(s => s.Birthday <= DateTime.Now.AddYears(-18));
            bool anyAdults = students.Any(s => s.Birthday <= DateTime.Now.AddYears(-18));
            bool containsWangWu = students.Contains(students.First(s => s.StudentName == "王五"));

更多方法查询

            var querySyntaxResult = from student in students
                                    where student.ClassID == 101
                                    orderby student.StudentName ascending
                                    select student;
Console.WriteLine("查询语法结果:");
            foreach (var student in querySyntaxResult)
            {
                Console.WriteLine($"{student.StudentName}, ClassID: {student.ClassID}");
            }

查询关键字:

  • from: 指定数据源和范围变量(类似于迭代变量)。

  • where: 基于由逻辑 AND 和 OR 运算符(&& 或 ||)分隔的一个或多个布尔表达式筛选源元素。

  • select: 指定执行查询时,所返回序列中元素的类型和形状。

  • group: 根据指定的密钥值对查询结果分组。

  • into: 提供可作为对 join、group 或 select 子句结果引用的标识符(简单理解用于将配对的结果收集到一个临时序列)。

  • orderby: 根据元素类型的默认比较器对查询结果进行升序或降序排序。

  • join: 基于两个指定匹配条件间的相等比较而联接两个数据源(简单理解根据指定的键将两个序列中的元素配对)。

  • let: 引入范围变量,在查询表达式中存储子表达式结果。

  • in: join子句中的上下文关键字。

  • on: join子句中的上下文关键字。

  • equals: join子句中的上下文关键字。

  • by: group 子句中的上下文关键字。

  • ascending: orderby子句中的上下文关键字。

  • descending: orderby子句中的上下文关键字。

    方法语法

    方法语法也称为扩展方法语法,使用点号“.”和一系列扩展方法来构建查询。

            var methodSyntaxResult = students
                                    .Where(student => student.ClassID == 101)
                                    .OrderBy(student => student.StudentName)
                                    .ToList();
Console.WriteLine("方法语法结果:");
            foreach (var student in methodSyntaxResult)
            {
                Console.WriteLine($"{student.StudentName}, ClassID: {student.ClassID}");
            }

混合查询和方法语法

            var mixedResult = (from student in students where student.ClassID == 101 where student.Courses.Any(course => course.CourseName == "数学") orderby student.StudentName ascending select student).Take(2).ToList();
			// 输出结果
			Console.WriteLine("混合查询结果:");
			foreach (var student in mixedResult)
			{
				Console.WriteLine($"{student.StudentName}, ClassID: {student.ClassID}"); 
			}

参考文章