C# LINQ

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

解释: 这里我们将studentsscores集合根据StudentId属性进行了连接,Join操作返回了每个学生的姓名和分数。

2.Aggregate(聚合运算)

Aggregate用于对集合中的元素进行累积运算。可以将其看作是一种更灵活的SumCount等操作,它允许你定义任意的累积计算逻辑。

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从第一个元素开始,将其与下一个元素相乘,直到处理完所有元素。结果是所有元素的乘积。

相关推荐
Algorithm15765 分钟前
JVM是什么,与Java的关系是什么,以及JVM怎么实现的跨平台性
java·开发语言·jvm
Gnevergiveup6 分钟前
2024网鼎杯青龙组Web+Misc部分WP
开发语言·前端·python
边疆.20 分钟前
C++类和对象 (中)
c语言·开发语言·c++·算法
yy_xzz22 分钟前
QT编译报错:-1: error: cannot find -lGL
开发语言·qt
铁手飞鹰24 分钟前
[linux驱动开发--环境搭建] qemu-9.1+linux-kernel-6.11
linux·服务器·驱动开发
wangsir.25 分钟前
线程的同步
linux·服务器·线程·同步
你不讲 wood25 分钟前
使用 Axios 上传大文件分片上传
开发语言·前端·javascript·node.js·html·html5
传输能手27 分钟前
从三方云服务器将数据迁移至本地,如何保障安全高效?
大数据·服务器·数据库
林浔090633 分钟前
C语言部分输入输出(printf函数与scanf函数,getchar与putchar详解,使用Linux ubuntu)
c语言·开发语言
一颗甜苞谷1 小时前
开源一款基于 JAVA 的仓库管理系统,支持三方物流和厂内物流,包含 PDA 和 WEB 端的源码
java·开发语言·开源