跳转到内容

C Sharp LINQ 查询语法

来自代码酷


C# LINQ 查询语法(Language Integrated Query)是 C# 语言中一种强大的数据查询技术,它允许开发者以声明式的方式对数据集合(如数组、列表、数据库等)进行查询和操作。LINQ 查询语法类似于 SQL,但完全集成在 C# 语言中,使得查询更加直观和类型安全。

简介[编辑 | 编辑源代码]

LINQ 查询语法提供了一种简洁、易读的方式来编写查询表达式。它由一系列关键字(如 `from`、`where`、`select`、`orderby` 等)组成,这些关键字允许开发者以类似 SQL 的语法编写查询。LINQ 查询语法最终会被编译器转换为方法调用(即 LINQ 方法语法),但查询语法通常更易于理解和维护。

LINQ 查询语法适用于以下数据源:

  • 内存中的集合(如 `List<T>`、`Array`)
  • 数据库(通过 Entity Framework 或 LINQ to SQL)
  • XML 文档(通过 LINQ to XML)
  • 其他支持 `IEnumerable<T>` 或 `IQueryable<T>` 的数据源

基本语法结构[编辑 | 编辑源代码]

一个典型的 LINQ 查询语法由以下部分组成: 1. **`from` 子句**:指定数据源和范围变量。 2. **`where` 子句**(可选):筛选数据。 3. **`orderby` 子句**(可选):排序数据。 4. **`select` 或 `group` 子句**:选择或分组数据。

以下是 LINQ 查询语法的基本模板:

var query = from 范围变量 in 数据源
            where 条件
            orderby 排序字段
            select 结果;

示例:查询整数列表中的偶数[编辑 | 编辑源代码]

以下是一个简单的 LINQ 查询语法示例,从一个整数列表中筛选出偶数并按升序排序:

using System;
using System.Linq;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

        var evenNumbers = from num in numbers
                          where num % 2 == 0
                          orderby num
                          select num;

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

输出:

2
4
6
8
10

解释: 1. `from num in numbers`:从 `numbers` 列表中取出每个元素,命名为 `num`。 2. `where num % 2 == 0`:筛选出能被 2 整除的数(偶数)。 3. `orderby num`:按升序排序。 4. `select num`:选择 `num` 作为结果。

关键子句详解[编辑 | 编辑源代码]

`from` 子句[编辑 | 编辑源代码]

`from` 子句是 LINQ 查询的起点,它指定了数据源和范围变量。范围变量类似于 `foreach` 循环中的迭代变量,表示数据源中的单个元素。

`where` 子句[编辑 | 编辑源代码]

`where` 子句用于筛选数据,它接受一个布尔表达式,只有满足条件的元素才会被包含在结果中。

`orderby` 子句[编辑 | 编辑源代码]

`orderby` 子句用于对结果进行排序。默认是升序(`ascending`),也可以显式指定降序(`descending`)。

`select` 子句[编辑 | 编辑源代码]

`select` 子句定义了查询结果的形状。可以选择原始元素、投影到新类型或计算字段。

`group` 子句[编辑 | 编辑源代码]

`group` 子句用于将数据按指定键分组。分组后的结果是一个 `IGrouping<TKey, TElement>` 集合。

`join` 子句[编辑 | 编辑源代码]

`join` 子句用于连接两个数据源,类似于 SQL 中的 `JOIN` 操作。

实际应用案例[编辑 | 编辑源代码]

案例 1:查询学生成绩[编辑 | 编辑源代码]

假设有一个 `Student` 类和一个 `Grade` 类,我们需要查询成绩高于 80 分的学生姓名和分数:

class Student
{
    public int Id { get; set; }
    public string Name { get; set; }
}

class Grade
{
    public int StudentId { get; set; }
    public int Score { get; set; }
}

class Program
{
    static void Main()
    {
        List<Student> students = new List<Student>
        {
            new Student { Id = 1, Name = "Alice" },
            new Student { Id = 2, Name = "Bob" },
            new Student { Id = 3, Name = "Charlie" }
        };

        List<Grade> grades = new List<Grade>
        {
            new Grade { StudentId = 1, Score = 85 },
            new Grade { StudentId = 2, Score = 75 },
            new Grade { StudentId = 3, Score = 90 }
        };

        var highScorers = from student in students
                          join grade in grades on student.Id equals grade.StudentId
                          where grade.Score > 80
                          select new { student.Name, grade.Score };

        foreach (var scorer in highScorers)
        {
            Console.WriteLine($"{scorer.Name}: {scorer.Score}");
        }
    }
}

输出:

Alice: 85
Charlie: 90

案例 2:分组查询[编辑 | 编辑源代码]

以下示例按学生姓名的首字母分组:

var groupedStudents = from student in students
                      group student by student.Name[0] into studentGroup
                      select new { FirstLetter = studentGroup.Key, Students = studentGroup };

foreach (var group in groupedStudents)
{
    Console.WriteLine($"Students with names starting with '{group.FirstLetter}':");
    foreach (var student in group.Students)
    {
        Console.WriteLine($"- {student.Name}");
    }
}

输出:

Students with names starting with 'A':
- Alice
Students with names starting with 'B':
- Bob
Students with names starting with 'C':
- Charlie

LINQ 查询语法 vs 方法语法[编辑 | 编辑源代码]

LINQ 查询语法和方法语法是等价的,查询语法会在编译时转换为方法语法。以下是一个对比示例:

查询语法:

var query = from num in numbers
            where num % 2 == 0
            select num;

方法语法:

var query = numbers.Where(num => num % 2 == 0);

性能注意事项[编辑 | 编辑源代码]

  • LINQ 查询是延迟执行的(除非调用 `ToList()` 或 `ToArray()` 等方法)。
  • 对于大型数据集,应考虑使用 `AsParallel()` 进行并行查询。
  • 在数据库查询中,LINQ 查询会被转换为 SQL,因此应避免在查询中使用复杂的本地逻辑。

总结[编辑 | 编辑源代码]

C# LINQ 查询语法提供了一种直观、声明式的方式来查询和操作数据。它的语法类似于 SQL,但完全集成在 C# 语言中,支持类型安全和编译时检查。通过 `from`、`where`、`select` 等关键字,开发者可以轻松地编写复杂的查询逻辑。无论是内存集合、数据库还是 XML,LINQ 都能提供一致的查询体验。

模板:C