C#中LINQ基础:101个常用LINQ操作

C#中LINQ基础:101个常用LINQ操作

LINQ(语言集成查询)是 C# 中的一个革命性特性,它彻底改变了开发人员处理数据的方式。无论你是刚刚开始学习 C#,还是希望提高编码技能,掌握 LINQ 都将显著提升你的工作效率和代码质量。

什么是 C# 中的 LINQ?

LINQ 将查询功能直接集成到 C# 语言中,提供了一种统一的方式来查询不同来源的数据——无论是数组、集合、数据库、XML 还是其他格式。通过在 C# 中使用 LINQ,你不再需要学习多种查询语言来处理不同的数据格式。

// 基本的 LINQ 查询示例
var numbers = new List<int> { 1, 2, 3, 4, 5 };
var evenNumbers = numbers.Where(n => n % 2 == 0);
// 结果:2, 4

101 个 C# 中常用的 LINQ 操作

让我们来探讨一些最常用的 LINQ 操作:

class LinqTutorials
{
    static void Main(string[] args)
    {
        Console.WriteLine("=== C# 中的 LINQ 教程:101 个 LINQ 操作 ===");

        // 基本集合初始化
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
        List<string> fruits = new List<string> { "apple", "banana", "cherry", "date" };
        List<int> moreNumbers = new List<int> { 5, 6, 7, 8, 9 };

        Console.WriteLine("=== 使用 Where 进行基本的 LINQ 过滤 ===");

        // 1. 基本的 Where 过滤
        var evenNumbers = numbers.Where(x => x % 2 == 0);
        Console.WriteLine("偶数: " + string.Join(", ", evenNumbers));
        // SQL: SELECT Number FROM Numbers WHERE Number % 2 = 0;
        // 结果: 2, 4

        // 2. 复杂的 Where 过滤
        var evenAndGreaterThan3 = numbers.Where(x => x % 2 == 0 && x > 3);
        Console.WriteLine("偶数且大于 3: " + string.Join(", ", evenAndGreaterThan3));
        // SQL: SELECT Number FROM Numbers WHERE Number % 2 = 0 AND Number > 3;
        // 结果: 4

        Console.WriteLine("\n=== C# 中的 LINQ Select 操作 ===");

        // 3. 简单的 Select 操作
        var same = numbers.Select(n => n);
        Console.WriteLine("相同的数字: " + string.Join(", ", same));
        // SQL: SELECT Number FROM Numbers;
        // 结果: 1, 2, 3, 4, 5

        // 4. 带变换的 Select 操作
        var doubled = numbers.Select(x => x * 2);
        Console.WriteLine("倍增后的数字: " + string.Join(", ", doubled));
        // SQL: SELECT Number * 2 AS DoubledNumber FROM Numbers;
        // 结果: 2, 4, 6, 8, 10

        // 5. 带匿名类型的 Select 操作
        var squares = numbers.Select(x => new { Number = x, Square = x * x });
        Console.WriteLine("平方数: " + string.Join(", ", squares));
        // SQL: SELECT Number, Number * Number AS Square FROM Numbers;
        // 结果: { Number = 1, Square = 1 }, { Number = 2, Square = 4 }, 等等。

        Console.WriteLine("\n=== 使用 LINQ 的 OrderBy 操作 ===");

        // 6. 基本的 OrderBy
        var orderedNumbers = numbers.OrderBy(n => n);
        Console.WriteLine("升序排列的数字: " + string.Join(", ", orderedNumbers));
        // SQL: SELECT Number FROM Numbers ORDER BY Number ASC;
        // 结果: 1, 2, 3, 4, 5

        // 7. 使用 OrderByDescending 排序
        var descendingNumbers = numbers.OrderByDescending(n => n);
        Console.WriteLine("降序排列的数字: " + string.Join(", ", descendingNumbers));
        // SQL: SELECT Number FROM Numbers ORDER BY Number DESC;
        // 结果: 5, 4, 3, 2, 1

        // 8. 多重排序条件
        var orderedFruits = fruits.OrderBy(x => x.Length).ThenBy(x => x);
        Console.WriteLine("按长度和字母顺序排序的水果: " + string.Join(", ", orderedFruits));
        // SQL: SELECT Name FROM Fruits ORDER BY LENGTH(Name) ASC, Name ASC;
        // 结果: date, apple, banana, cherry

        Console.WriteLine("\n=== LINQ 的 GroupBy 操作 ===");

        // 9. GroupBy 操作
        var groupedByRemainder = numbers.GroupBy(x => x % 3);
        foreach (var group in groupedByRemainder)
        {
            Console.WriteLine($"余数为 {group.Key} 的数字: {string.Join(", ", group)}");
        }
        // SQL: SELECT Number % 3 AS Remainder, Number FROM Numbers GROUP BY Number % 3;
        // 结果:
        // 余数为 1 的数字: 1, 4
        // 余数为 2 的数字: 2, 5
        // 余数为 0 的数字: 3

        Console.WriteLine("\n=== 使用 LINQ 的 Join 操作 ===");

        List<Student> students = new List<Student>
    {
        new Student { ID = 1, Name = "Alice", Age = 21 },
        new Student { ID = 2, Name = "Bob", Age = 23 },
        new Student { ID = 3, Name = "Charlie", Age = 20 }
    };

        List<Course> courses = new List<Course>
    {
        new Course { StudentID = 1, CourseName = "Math" },
        new Course { StudentID = 1, CourseName = "Physics" },
        new Course { StudentID = 2, CourseName = "Chemistry" },
        new Course { StudentID = 3, CourseName = "Biology" }
    };

        // 10. 内连接操作(Inner Join)
        var studentCourses = students.Join(
            courses,
            student => student.ID,
            course => course.StudentID,
            (student, course) => new { student.Name, course.CourseName }
        );

        Console.WriteLine("学生与课程 (内连接):");
        foreach (var item in studentCourses)
        {
            Console.WriteLine($"{item.Name} 正在学习 {item.CourseName}");
        }
        // SQL: SELECT s.Name, c.CourseName FROM Students s INNER JOIN Courses c ON s.ID = c.StudentID;
        // 结果:
        // Alice 正在学习 Math
        // Alice 正在学习 Physics
        // Bob 正在学习 Chemistry
        // Charlie 正在学习 Biology

        Console.WriteLine("\n=== C# 中的 LINQ 集合操作 ===");

        // 11. 并集操作(Union)
        var union = numbers.Union(moreNumbers);
        Console.WriteLine("并集: " + string.Join(", ", union));
        // SQL: SELECT Number FROM Numbers UNION SELECT Number FROM MoreNumbers;
        // 结果: 1, 2, 3, 4, 5, 6, 7, 8, 9

        // 12. 交集操作(Intersect)
        var intersection = numbers.Intersect(moreNumbers);
        Console.WriteLine("交集: " + string.Join(", ", intersection));
        // SQL: SELECT Number FROM Numbers INTERSECT SELECT Number FROM MoreNumbers;
        // 结果: 5

        // 13. 差集操作(Except)
        var except = numbers.Except(moreNumbers);
        Console.WriteLine("差集: " + string.Join(", ", except));
        // SQL: SELECT Number FROM Numbers EXCEPT SELECT Number FROM MoreNumbers;
        // 结果: 1, 2, 3, 4

        Console.WriteLine("\n=== LINQ 元素操作教程 ===");

        // 14. First 操作
        var first = numbers.First();
        Console.WriteLine("第一个数字: " + first);
        // SQL: SELECT TOP 1 Number FROM Numbers;
        // 结果: 1

        // 15. 带条件的 First 操作
        var firstEven = numbers.First(n => n % 2 == 0);
        Console.WriteLine("第一个偶数: " + firstEven);
        // SQL: SELECT TOP 1 Number FROM Numbers WHERE Number % 2 = 0;
        // 结果: 2

        // 16. FirstOrDefault 操作
        var firstOver10 = numbers.FirstOrDefault(n => n > 10);
        Console.WriteLine("第一个大于 10 的数字 (或默认值): " + firstOver10);
        // SQL: SELECT TOP 1 Number FROM Numbers WHERE Number > 10;
        // 结果: 0(默认值)

        //

        // 17. Last 操作
        var last = numbers.Last();
        Console.WriteLine("最后一个数字: " + last);
        // SQL: SELECT TOP 1 Number FROM Numbers ORDER BY Number DESC;
        // 结果: 5

        // 18. LastOrDefault 操作
        var lastOver10 = numbers.LastOrDefault(n => n > 10);
        Console.WriteLine("最后一个大于 10 的数字 (或默认值): " + lastOver10);
        // SQL: SELECT TOP 1 Number FROM Numbers WHERE Number > 10 ORDER BY Number DESC;
        // 结果: 0(默认值)
        // 19. ElementAt
        var elementAt = numbers.ElementAt(2);
        Console.WriteLine("Element at index 2: " + elementAt);
        // SQL equivalent would require ROW_NUMBER() or similar
        // Result: 3

        Console.WriteLine("\n=== 101 LINQ Examples: Quantifier Operations ===");

        // 20. Any
        bool hasEven = numbers.Any(n => n % 2 == 0);
        Console.WriteLine("Has even numbers: " + hasEven);
        // SQL: SELECT CASE WHEN EXISTS (SELECT 1 FROM Numbers WHERE Number % 2 = 0) THEN 1 ELSE 0 END;
        // Result: True

        // 21. All
        bool allPositive = numbers.All(n => n > 0);
        Console.WriteLine("All numbers positive: " + allPositive);
        // SQL: SELECT CASE WHEN NOT EXISTS (SELECT 1 FROM Numbers WHERE NOT (Number > 0)) THEN 1 ELSE 0 END;
        // Result: True

        // 22. Contains
        bool contains3 = numbers.Contains(3);
        Console.WriteLine("Contains 3: " + contains3);
        // SQL: SELECT CASE WHEN EXISTS (SELECT 1 FROM Numbers WHERE Number = 3) THEN 1 ELSE 0 END;
        // Result: True

        Console.WriteLine("\n=== LINQ Partitioning Tutorial ===");

        // 23. Take
        var firstThree = numbers.Take(3);
        Console.WriteLine("First 3 numbers: " + string.Join(", ", firstThree));
        // SQL: SELECT TOP 3 Number FROM Numbers;
        // Result: 1, 2, 3

        // 24. Skip
        var skipTwo = numbers.Skip(2);
        Console.WriteLine("Skip first 2 numbers: " + string.Join(", ", skipTwo));
        // SQL: SELECT Number FROM Numbers ORDER BY (SELECT NULL) OFFSET 2 ROWS;
        // Result: 3, 4, 5

        // 25. TakeWhile
        var takeWhileLessThan4 = numbers.TakeWhile(n => n < 4);
        Console.WriteLine("Take while < 4: " + string.Join(", ", takeWhileLessThan4));
        // SQL: SELECT Number FROM Numbers WHERE Number < 4;
        // Result: 1, 2, 3

        // 26. SkipWhile
        var skipWhileLessThan4 = numbers.SkipWhile(n => n < 4);
        Console.WriteLine("Skip while < 4: " + string.Join(", ", skipWhileLessThan4));
        // SQL: SELECT Number FROM Numbers WHERE Number >= 4;
        // Result: 4, 5
    }
}

// 学生类
class Student
{
    public int ID { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

// 课程类
class Course
{
    public int StudentID { get; set; }
    public string CourseName { get; set; }
}

在 C# 中使用 LINQ:关键操作符解析

使用 Where 进行过滤
Where 操作符根据谓词过滤集合:

var evenNumbers = numbers.Where(n => n % 2 == 0);

使用 Select 进行转换
Select 操作符对每个元素进行转换:

var doubled = numbers.Select(n => n * 2);

使用 OrderBy 进行排序
OrderBy 操作符按升序排序元素:

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

使用 GroupBy 进行分组
GroupBy 操作符根据键将元素分组:

var groupedByRemainder = numbers.GroupBy(n => n % 3);

使用 Join 连接集合
Join 操作符将两个集合中的元素进行连接:

var studentCourses = students.Join(courses,
    student => student.ID,
    course => course.StudentID,
    (student, course) => new { student.Name, course.CourseName });

结论

我最喜欢 LINQ 的地方是,它让我更多地关注我需要什么数据,而不是怎么去获取它。像 Where、Select 和 OrderBy 这些操作符能够连贯地串联在一起,使用起来非常自然,并且清晰地表达了我的意图。当我在阅读包含 LINQ 的代码时,我能够快速理解它的目标。

虽然我仍在学习,但 LINQ 已经成为我写 C# 代码的一个重要部分。无论是处理简单的列表、复杂的对象,还是数据库查询,LINQ 都提供了一种一致的方式来表达我的数据需求,这对我来说非常有价值。我很期待继续探索更多 LINQ 操作,发现用这个强大的工具解决问题的新方法。

注:转载文章,大家觉得上面文章如何?欢迎留言讨论。

本文使用chatgpt协助翻译。

作者:Sridharan D,版权归原作者Sridharan D所有

原文链接:
c-sharpcorner.com/article/linq-in-c-sharp-tutorial-for-beginners-101-c-sharp-linq-operations/

https://mp.weixin.qq.com/s/NJsZcqfGlHwSpSSEsu7Rpw

Leave a Reply

Your email address will not be published. Required fields are marked *