LINQ(Language Integrated Query) 是C#中的一共强大工具,它允许你使用类似SQL的查询语法来操作集合(如数组、列表等)和数据源(如数据库、XML等)。LINQ使得查询更加简洁、直观,能够在编译时进行类型检查并提供良好的IDE支持。LINQ有多种形式,比如用于内存集合的LINQ to Objects、用于数据库的LINQ to SQL、用于LINQ to XML等等。
1、基本概念
LINQ查询主要有两种语法:
1.查询表达式语法(Query Syntax):这种语法类似于SQL语法。
2.方法语法(Method Syntax):这种语法是通过调用方法链来实现的,基于委托和lambda表达式。
两者最终都会编译成相同的代码,其中,方法语法使用更广泛。
2、查询表达式语法(Query Syntax)
查询表达式语法通常用于需要对集合进行筛选、排序和投影等操作。
cs
//查询表达式语法的例子
int[] numbers = {1,2,3,4,5,6,7,8,9};
//使用查询表达式语法查找所有偶数
var evenNumbers = from n in numbers
where n % 2 == 0
select n;
foreach(var num in evenNumbers)
{
Console.WriteLine(num);
}
在这个例子中,from指定要查询的集合,where是筛选条件,select是返回结果的形式。
3、方法语法(Method Syntax)
方法语法是通过调用链式的扩展方法来实现的,通常更具灵活性和可读性。它更依赖于lambda表达式。
cs
//方法语法例子
int[] numbers = {1,2,3,4,5,6,7,8,9,10};
var evenNumbers = num.Where(n => n % 2 == 0);
foreach(var num in evenNumbers)
{
Console.WriteLine(num);
}
这里,Where方法使用了Lambda表达式 n => n % 2 == 0作为筛选条件。
4、常用LINQ操作符
LINQ提供了一系列操作符用于查询和操作集合,这些操作符可以分为几类:
a.筛选操作符
• Where:用于筛选符合条件的元素。
cs
var adults = people.Where(p => p.Age >= 18);
b.投影操作符
• Select:将集合中的每个元素投影成新形式。
cs
var names = people.Select(p => p.Name);
c.排序操作符
• OrderBy:对结果进行升序排序。
• OrderByDescending:对结果进行降序排序。
cs
var sortedPeople = people.OrderBy(p => p.Age);
d.集合操作符
• Distinct:去除重复元素。
• Union、Intersect、Except:集合的并集、交集、差集操作。
cs
var distinctNumbers = numbers.Distinct();
e. 分组操作符
• GroupBy:按某个键值对集合进行分组。
cs
var groupedPeople = people.GroupBy(p => p.City);
f.聚合操作符
• Count:计算元素的个数。
• Sum:求和。
• Average:计算平均值。
• Max/Min:查找最大/最小值。
cs
var totalAge = people.Sum(p => p.Age);
5、复制查询示例
使用LINQ你可以构造复杂的查询,比如同时筛选、排序、分组等:
cs
//查找所有年龄大于18岁的人,按年龄排序并按城市分组
var query = from n in people
where p.Age > 18
orderBy p.Age
group p by p.City into cityGroup
select new
{
City = cityGroup.key,
People = CityGroup
};
foreach(var group in query)
{
Console.WriteLine($"City: {group.City}");
foreach (var person in group.People)
{
Console.WriteLine($" - {person.Name}, Age: {person.Age}");
}
}
6、延迟执行(Deferrde Execution)
LINQ查询默认是延迟执行的,意思是查询不会立即执行,而是当你遍历结果时才执行。这种特性可以挺高效率,特别是当集合非常大时。
cs
// 延迟执行示例
var query = numbers.Where(n => n > 5);
// 查询只在使用结果时执行
foreach (var num in query)
{
Console.WriteLine(num);
}
7、即时执行(Immediate Execution)
有些操作会触发LINQ的即时执行,比如ToList()
、ToArray()
、Count()
等。
cs
// 即时执行示例
var resultList = numbers.Where(n => n > 5).ToList();
8、更高级的LINQ操作:Join 和 Aggregate
1.Join(连接查询)
Join操作符用于将两个集合(如两个表或列表)根据某个键值进行关联。类似于SQL中的JOIN操作。
下面的例子展示如何通过Join将两个集合按照某个共同的属性(如Id)进行关联。
cs
var students = new[]
{
new { StudentId = 1, Name = "John" },
new { StudentId = 2, Name = "Jane" },
new { StudentId = 3, Name = "Tom" }
};
var scores = new[]
{
new { StudentId = 1, Score = 85 },
new { StudentId = 2, Score = 90 },
new { StudentId = 3, Score = 78 },
new { StudentId = 1, Score = 88 }
};
var query = from student in students
join score in scores
on student.StudentId equals score.StudentId
select new
{
student.Name,
score.Score
};
foreach (var result in query)
{
Console.WriteLine($"Student: {result.Name}, Score: {result.Score}");
}
输出:
cs
Student: John, Score: 85
Student: John, Score: 88
Student: Jane, Score: 90
Student: Tom, Score: 78
解释: 这里我们将students
和scores
集合根据StudentId
属性进行了连接,Join
操作返回了每个学生的姓名和分数。
2.Aggregate(聚合运算)
Aggregate
用于对集合中的元素进行累积运算。可以将其看作是一种更灵活的Sum
、Count
等操作,它允许你定义任意的累积计算逻辑。
cs
int[] numbers = { 1, 2, 3, 4, 5 };
// 使用Aggregate计算累积乘积
int product = numbers.Aggregate((acc, num) => acc * num);
Console.WriteLine($"Product of numbers: {product}");
输出:
cs
Product of numbers: 120
解释: 这里的Aggregate
从第一个元素开始,将其与下一个元素相乘,直到处理完所有元素。结果是所有元素的乘积。