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 都能提供一致的查询体验。