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

相关推荐
程序猿小D10 分钟前
第三百三十节 Java网络教程 - Java网络UDP服务器
java·开发语言·网络·网络协议·udp·多线程
努力中的小胖纸13 分钟前
python --基础阶段--文件操作(5)
开发语言·python
折枝寄北13 分钟前
C指针之舞——指针探秘之旅(2)
c语言·开发语言
八荒我为王15 分钟前
c#编码技巧(十九):各种集合特点汇总
c#·.net
螺旋天光极锐斩空闪壹式!17 分钟前
第十三课 二维数组(2)方向数组
开发语言·c++·算法
Crossoads26 分钟前
【汇编语言】call 和 ret 指令(一) —— 探讨汇编中的ret和retf指令以及call指令及其多种转移方式
android·开发语言·javascript·汇编·人工智能·数据挖掘·c#
十五年专注C++开发27 分钟前
C++不完整类型(Incomplete Type)的检测与避免
开发语言·c++·算法·设计模式
风掣长空32 分钟前
C++11————线程库
开发语言·c++
心死翼未伤37 分钟前
python从入门到精通:pyspark实战分析
开发语言·数据结构·python·spark·json
码农飞飞2 小时前
详解Rust结构体struct用法
开发语言·数据结构·后端·rust·成员函数·方法·结构体