摘要:本篇文章较为详细地介绍了 C# 当中的 LINQ 查询,主要包括 LINQ 提供程序、语法、查询变量以及使用 LINQ 查询 XML 几个方面。
1. 什么是LINQ?
LINQ(Language Integrated Query,发音同link)是 C# 语言中用于查询和操作数据集合的一种强大工具。LINQ 的核心思想是使查询语法成为语言的一部分,它允许我们以类似 SQL 的方式查询数组、集合、数据库、XML、甚至其他类型的数据源。通过使用 LINQ,开发人员可以以简洁、清晰的方式操作数据集合,同时还提供了编译时的类型检查。
LINQ的特点:
• 类型安全和编译时检查
• 集成在 C# 语言中,统一了查询操作的风格
• 支持多种数据源(如集合、数据库、XML、JSON等)
看一个例子:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
// 定义一个字典,键是字符串,值是整数
Dictionary<string, int> students = new Dictionary<string, int>
{
{ "Alice", 85 },
{ "Bob", 92 },
{ "Charlie", 78 },
{ "David", 90 },
{ "Eve", 88 }
};
// 使用LINQ查询字典中分数大于85的学生
var topStudents = from student in students
where student.Value > 85
select student;
Console.WriteLine("分数大于85的学生:");
foreach (var student in topStudents)
{
Console.WriteLine($"姓名: {student.Key}, 分数: {student.Value}");
}
// 另一种使用方法语法查询字典的方式
var highScoringStudents = students.Where(s => s.Value > 85)
.OrderBy(s => s.Key);
Console.WriteLine("\n方法语法查询:");
foreach (var student in highScoringStudents)
{
Console.WriteLine($"姓名: {student.Key}, 分数: {student.Value}");
}
}
}
输出结果:
分数大于85的学生:
姓名: Bob, 分数: 92
姓名: David, 分数: 90
姓名: Eve, 分数: 88
方法语法查询:
姓名: Bob, 分数: 92
姓名: David, 分数: 90
姓名: Eve, 分数: 88
2. LINQ提供程序
LINQ不仅仅限于内存中的对象集合,它还支持多种数据源。这是通过不同的LINQ提供程序实现的。对于查询的数据源,背后对应的根据该数据源实现 LINQ 查询的代码模块就叫 LINQ 提供程序。常见的 LINQ 提供程序包括:
- LINQ to Objects:对内存中的对象集合(如数组、List、Dictionary等)进行查询。
- LINQ to SQL:对SQL Server数据库进行查询。
- LINQ to XML:对XML数据进行查询。
- LINQ to Entities:通过Entity Framework对数据库进行查询。
这些提供程序为不同的数据源提供了统一的查询接口,开发人员可以使用相同的语法进行查询。
3. 方法语法和查询语法
LINQ支持两种语法风格:方法语法和查询语法。
• 方法语法:通过使用扩展方法来编写LINQ查询。
• 查询语法:类似于SQL查询的风格。
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// 方法语法
var evenNumbersMethodSyntax = numbers.Where(n => n % 2 == 0).ToList();
Console.WriteLine("方法语法:偶数");
evenNumbersMethodSyntax.ForEach(Console.WriteLine);
// 查询语法
var evenNumbersQuerySyntax = (from number in numbers
where number % 2 == 0
select number).ToList();
Console.WriteLine("\n查询语法:偶数");
evenNumbersQuerySyntax.ForEach(Console.WriteLine);
}
}
输出:
方法语法:偶数
2
4
6
8
10
查询语法:偶数
2
4
6
8
10
4. 查询变量
LINQ查询的执行是延迟的,即查询在定义时并不会立即执行,而是在实际枚举时才执行。查询变量只是对查询的定义。就是说,程序当中需要使用到查询变量的值的时候,才会真正执行LINQ 查询语句。
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
List<string> fruits = new List<string> { "Apple", "Banana", "Cherry", "Date" };
// 查询变量
var query = from fruit in fruits
where fruit.StartsWith("C")
select fruit;
Console.WriteLine("执行查询前添加元素");
fruits.Add("Cranberry");
// 执行查询
foreach (var fruit in query)
{
Console.WriteLine(fruit);
}
}
}
输出:
执行查询前添加元素
Cherry
Cranberry
5. 查询表达式的结构
LINQ查询语法类似于 SQL 语句,由多个关键字组成,每个关键字对应不同的操作。以下是常见的查询关键字:
• from:指定数据源。
• where:定义查询条件。
• select:指定返回的数据形式。
• join:执行连接操作。
• orderby:对结果进行排序。
示例代码:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
List<string> fruits = new List<string> { "Apple", "Banana", "Cherry", "Date", "Cranberry" };
// 查询语法
var query = from fruit in fruits
where fruit.Length > 5
orderby fruit
select fruit;
Console.WriteLine("长度大于5的水果,并按字母顺序排序:");
foreach (var fruit in query)
{
Console.WriteLine(fruit);
}
}
}
输出:
长度大于5的水果,并按字母顺序排序:
Banana
Cranberry
6. 标准查询运算符
LINQ 的标准查询运算符(Standard Query Operators)是对数据集合进行操作的一组方法,它们为数据的筛选、投影、排序、分组、连接和聚合提供了统一的接口。这些运算符大部分作为扩展方法定义在 System.Linq
命名空间中,并且可以用于实现对各种数据源(如数组、列表、字典、数据库、XML等)的操作。
下面是常见的LINQ标准查询运算符的分类及其功能:
名称 | 种类 | 作用 | 用法举例 |
---|---|---|---|
Where | 过滤运算符 | 用于筛选满足指定条件的元素。 | var evenNumbers = numbers.Where(n => n % 2 == 0); |
Select | 投影运算符 | 用于将集合中的每个元素转换为另一种形式。 | var squareNumbers = numbers.Select(n => n * n); |
OrderBy | 排序运算符 | 用于将元素按升序排序。 | var orderedNumbers = numbers.OrderBy(n => n); |
ThenBy | 排序运算符 | 用于在第一次排序之后进行第二次排序(升序)。 | var sortedPeople = people.OrderBy(p => p.LastName).ThenBy(p => p.FirstName); |
GroupBy | 分组运算符 | 用于根据某个键将元素分组。 | var groupedByFirstLetter = words.GroupBy(word => word[0]); |
Join | 连接运算符 | 用于将两个数据源按指定键连接起来,类似于SQL中的内连接。 | var joinResult = people.Join(departments, p => p.DepartmentId, d => d.Id, (p, d) => new { p.Name, d.DepartmentName }); |
7. LINQ to XML
LINQ to XML是 LINQ 的一个扩展,它允许我们以LINQ的方式操作XML数据。通过使用System.Xml.Linq
命名空间,开发者可以轻松地加载、查询和操作XML数据。
示例代码:
using System;
using System.Linq;
using System.Xml.Linq;
class Program
{
static void Main()
{
string xmlData = @"
<Fruits>
<Fruit>
<Name>Apple</Name>
<Color>Red</Color>
</Fruit>
<Fruit>
<Name>Banana</Name>
<Color>Yellow</Color>
</Fruit>
<Fruit>
<Name>Cherry</Name>
<Color>Red</Color>
</Fruit>
</Fruits>";
// 加载XML数据
XElement fruitsXml = XElement.Parse(xmlData);
// 查询红色的水果
var redFruits = from fruit in fruitsXml.Elements("Fruit")
where fruit.Element("Color").Value == "Red"
select fruit.Element("Name").Value;
Console.WriteLine("红色的水果:");
foreach (var fruit in redFruits)
{
Console.WriteLine(fruit);
}
}
}
输出:
红色的水果:
Apple
Cherry
通过这篇博客,希望你能对C#语言中的LINQ有一个初步的了解,并能够应用于实际开发中。LINQ不仅提供了便捷的查询方式,还统一了不同数据源的操作模式,让编写复杂查询变得更加容易和直观。
各位道友,如有收获,记得一键三连呐。
最后,给各位道友介绍一下使用国外虚拟卡开通一些国外服务的渠道,当前我在用的是 wildcard,使用我的注册邀请码 IOQ1YDHH
注册,能得 2 美刀,抵消一部分的开卡费用。自己买个 Github Copilot
、ChatGPT Plus
(无需注册,可半价购买)简直不要太香。