C# --- LINQ

C# --- LINQ

  • 什么是LINQ
  • Fluent Syntax 和 SQL-Like Query
  • LINQ Operations

什么是LINQ

  • LINQ的全称为Language Integrated Query, 为各种查询(包括对象查询,数据库查询,XML查询) 提供了统一模型.
  • LINQ源于SQL,但比SQL更加强大,更加灵活.
  • LINQ可以用类似于SQL的形式对C# Collection中的对象进行查询
  • LINQ可以在代码中对数据库进行查询,编程语言和数据库之间配合上的鸿沟,也就是不用再手动拼接SQL字符串去查询数据库.
  • 可读性强:LINQ增加了代码的可读性,因此其他开发人员可以很轻松地理解和维护

Fluent Syntax 和 SQL-Like Query

  • LINQ 在C#中分为两种主要语法形式

方法语法(Method Syntax / Fluent Syntax)

  • 使用 扩展方法(如 Where(), Select())链式调用,直接操作集合或数据源。
  • 特点:
    基于 Lambda 表达式,灵活且功能全面。
    支持所有 LINQ 操作(某些操作仅能通过方法语法实现,如 Distinct())。
    可读性取决于链式调用的复杂度。
var results = students.Where(s => s.Age > 18).OrderBy(s => s.Name).Select(s => new { s.Name, s.Score });

2. 查询表达式语法(Query Syntax / SQL-like Syntax)

  • 使用类似 SQL 的声明式语法,以 from、where、select 等关键字编写。
  • 特点:
    语法更接近自然语言,适合复杂查询(如多表连接、分组)。
    编译时会转换为方法语法(本质是语法糖)。
    部分操作无法直接表达(需结合方法语法,如 Distinct())。
var results = from s in studentswhere s.Age > 18orderby s.Nameselect new { s.Name, s.Score };

混合使用示例

// 结合查询表达式和方法语法
var query = (from s in studentswhere s.Age > 18select s).Distinct().ToList();

总结

  • 方法语法:灵活、全面,适合大多数场景。
  • 查询表达式:提升复杂查询的可读性,尤其适合多表操作。
  • 本质一致:两种语法最终殊途同归,按需选择即可!

LINQ Operations

Where(过滤)

var students = new List<Student> { /* 学生对象列表 */ };
// 找到年龄大于 20 的学生
var result = students.Where(s => s.Age > 20);

Select(投影)

// 提取所有学生的姓名
var names = students.Select(s => s.Name);

OrderBy / OrderByDescending(排序)

// 按年龄升序排序
var ordered = students.OrderBy(s => s.Age);
// 按成绩降序排序
var orderedByScore = students.OrderByDescending(s => s.Score);

GroupBy(分组)

// 按班级分组
var groups = students.GroupBy(s => s.Class);// 遍历分组
foreach (var group in groups) {Console.WriteLine($"Class {group.Key}:");foreach (var student in group) {Console.WriteLine(student.Name);}
}

First / FirstOrDefault(获取首个元素)

// 获取第一个年龄大于 20 的学生(可能抛异常)
var first = students.First(s => s.Age > 20);
// 安全获取(无匹配返回 null)
var firstOrDefault = students.FirstOrDefault(s => s.Age > 100);

Single / SingleOrDefault(唯一元素)

// 确保唯一匹配(否则抛异常)
var single = students.Single(s => s.Id == 123);
// 安全获取唯一元素
var singleOrDefault = students.SingleOrDefault(s => s.Id == 456);

Any / All(存在性检查)

// 是否有学生年龄 > 20
bool hasAdult = students.Any(s => s.Age > 20);
// 是否所有学生成绩 >= 60
bool allPassed = students.All(s => s.Score >= 60);

Count / Sum / Average(聚合)

// 统计年龄 > 20 的学生数量
int count = students.Count(s => s.Age > 20);
// 计算所有学生的平均分
double avgScore = students.Average(s => s.Score);
// 总成绩
double totalScore = students.Sum(s => s.Score);

Take / Skip(分页)

// 取前 5 条数据
var page1 = students.Take(5);
// 跳过前 5 条,取接下来的 5 条(分页)
var page2 = students.Skip(5).Take(5);

Join(连接)

var courses = new List<Course> { /* 课程列表 */ };
// 学生与课程通过 CourseId 连接
var joined = students.Join(courses,s => s.CourseId,c => c.Id,(s, c) => new { s.Name, CourseName = c.Name }
);

Distinct(去重)

// 去重后的所有班级名称
var distinctClasses = students.Select(s => s.Class).Distinct();

SelectMany(扁平化嵌套集合)

var classes = new List<Class> { /* 班级列表(含学生集合) */ };
// 所有班级的所有学生
var allStudents = classes.SelectMany(c => c.Students);

Union / Intersect / Except(集合操作)

var list1 = new List<int> { 1, 2, 3 };
var list2 = new List<int> { 3, 4, 5 };var union = list1.Union(list2);          // {1,2,3,4,5}
var intersect = list1.Intersect(list2);  // {3}
var except = list1.Except(list2);        // {1,2}

OfType / Cast(类型筛选)

var mixedList = new ArrayList { 1, "apple", 2, "banana" };
// 提取所有字符串
var strings = mixedList.OfType<string>();

Aggregate(自定义聚合)

//对集合元素执行累积操作
int[] numbers = { 1, 2, 3, 4 };
// 计算乘积:1*2*3*4
int product = numbers.Aggregate((acc, num) => acc * num);
// 指定初始值(例如累加字符串)
string concatenated = numbers.Aggregate("", (acc, num) => acc + num.ToString());

Max / Min(极值)

var maxAge = students.Max(s => s.Age);
var minScore = students.Min(s => s.Score);

Last / LastOrDefault(获取最后一个元素)

// 最后一个年龄大于 20 的学生
var last = students.Last(s => s.Age > 20);
var lastOrDefault = students.LastOrDefault(s => s.Age > 100);

Reverse(反转顺序)

var reversed = numbers.Reverse(); // {4,3,2,1}

Concat(连接两个集合)

var list1 = new List<int> { 1, 2 };
var list2 = new List<int> { 3, 4 };
var combined = list1.Concat(list2); // {1,2,3,4}

SequenceEqual(判断集合相等性)

var listA = new List<int> { 1, 2 };
var listB = new List<int> { 1, 2 };
bool isEqual = listA.SequenceEqual(listB); // true

DefaultIfEmpty(空集合默认值)

var emptyList = new List<int>();
// 若集合为空,返回包含默认值的单元素集合
var result = emptyList.DefaultIfEmpty(0); // {0}

Zip(合并两个集合)

var names = new[] { "Alice", "Bob" };
var ages = new[] { 25, 30 };
// 合并为元组:("Alice",25), ("Bob",30)
var zipped = names.Zip(ages, (name, age) => (name, age));

ToDictionary / ToLookup(转换为字典或分组字典)

// 将学生列表转为以Id为键的字典
var dict = students.ToDictionary(s => s.Id);
// 创建分组查找结构(类似 GroupBy,但立即执行)
var lookup = students.ToLookup(s => s.Class);

TakeWhile / SkipWhile(条件分页)

int[] nums = { 1, 2, 3, 4, 5, 1 };
// 取元素直到遇到 >=3 的值
var takeWhile = nums.TakeWhile(n => n < 3); // {1,2}
// 跳过元素直到遇到 >=3 的值
var skipWhile = nums.SkipWhile(n => n < 3); // {3,4,5,1}

ElementAt / ElementAtOrDefault(按索引访问)

var thirdStudent = students.ElementAt(2); // 索引从0开始
var safeElement = students.ElementAtOrDefault(100); // 越界返回 null

Range / Repeat(生成序列)

// 生成数字序列 10-14
var range = Enumerable.Range(10, 5); // {10,11,12,13,14}
// 生成重复值
var repeats = Enumerable.Repeat("Hello", 3); // {"Hello","Hello","Hello"}

Cast(强制类型转换)

var mixedList = new ArrayList { 1, 2, 3 };
// 转换为 IEnumerable<int>
var numbers = mixedList.Cast<int>();

DistinctBy / UnionBy(基于属性的去重/合并)

(需 .NET 6+ 或引入 System.Linq 的扩展包)
// 根据班级去重
var distinctByClass = students.DistinctBy(s => s.Class);
// 合并并去重(根据ID)
var unionBy = list1.UnionBy(list2, x => x.Id);

Chunk(分块)

//(需 .NET 6+)
int[] numbers = { 1, 2, 3, 4, 5 };
// 每块大小为2
var chunks = numbers.Chunk(2); // { {1,2}, {3,4}, {5} }

AsParallel(并行查询)

var bigData = Enumerable.Range(1, 1000000);
// 并行处理
var parallelResult = bigData.AsParallel().Where(n => n % 2 == 0).ToList();

OfType(过滤类型)

object[] objs = { 1, "apple", 2, "banana" };
// 提取所有整数
var ints = objs.OfType<int>(); // {1,2}

Prepend / Append(添加元素)

var nums = new[] { 2, 3 };
var newNums = nums.Prepend(1).Append(4); // {1,2,3,4}

LongCount(大集合计数)

// 返回 long 类型的计数(适用于超大集合)
long count = bigData.LongCount();

TakeLast / SkipLast(获取或跳过末尾元素)

int[] numbers = { 1, 2, 3, 4, 5 };
var lastTwo = numbers.TakeLast(2);       // {4,5}
var skipLastThree = numbers.SkipLast(3); // {1,2}

MaxBy / MinBy(按属性取极值对象)

//(需 .NET 6+)
// 取分数最高的学生
var topStudent = students.MaxBy(s => s.Score);
// 取年龄最小的学生
var youngest = students.MinBy(s => s.Age);

ToHashSet(快速去重集合)

//(需 .NET Framework 4.7.2+ 或 .NET Core 2.0+)
var uniqueNumbers = new[] { 1, 2, 2, 3 }.ToHashSet(); // {1,2,3}

ExceptBy / IntersectBy(基于键的集合操作)

var listA = new[] { new { Id = 1 }, new { Id = 2 } };
var listB = new[] { new { Id = 2 }, new { Id = 3 } };
// 按 Id 排除交集
var except = listA.ExceptBy(listB.Select(x => x.Id), x => x.Id); // {Id=1}

AsEnumerable / AsQueryable(切换执行上下文)

// 将 IQueryable 转为 IEnumerable(后续操作在内存执行)
var inMemoryQuery = dbContext.Students.AsEnumerable().Where(s => s.Age > 20);
// 将 IEnumerable 转为 IQueryable(用于动态构建数据库查询)
var queryable = students.AsQueryable().Where(s => s.Age > 20);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/72442.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【AI News | 20250316】每日AI进展

AI Repos 1、ReActMCP 将网络搜索能力集成到AI助手中的一个MCP服务&#xff1a;ReActMCP Web Search&#xff0c;相当于给AI装了个搜索引擎&#xff0c;可以实时查找最新的内容。它基于Exa API执行基本和高级网络搜索&#xff0c;高级搜索比如限制搜索的网站范围、指定日期范围…

【VUE】day04-组件的生命周期、组件之间的数据共享、ref引用、购物车案例

【VUE】day04-组件的生命周期、组件之间的数据共享、ref引用、购物车案例 1. 组件之间的关系2. 使用组件的三个步骤3. vue.components全局注册组件4. 自动生成右边标签插件5. 组件的props6. 结合v-bind使用自定义属性7. props的默认default值8. type值类型9. 组件之间的样式冲突…

Redis分布式锁深度剖析:从原理到Redisson实战,破解脑裂与高并发锁难题

一、&#x1f4cc; 分布式锁的核心应用场景 场景类型典型案例风险说明&#x1f680; 高并发场景电商秒杀、票务抢购库存超卖风险⏰ 定时任务场景集群日志清理、数据统计任务重复执行&#x1f504; 幂等场景支付接口重试、订单创建资金重复扣款 二、&#x1f527; Redis分布式锁…

量化交易学习笔记02:双均线策略

双均线策略示例 个股&#xff1a;中国平安 回测日期&#xff1a;2022-5-1至2023-5-1 短均线&#xff1a;5天 长无线&#xff1a;10天 代码&#xff1a; def initialize(context):# 初始化此策略# 设置我们要操作的股票池, 这里我们只操作一支股票# """标的&qu…

交换机控制软件的实现步骤猜测

一、主要目的 提出对交换机软件控制逻辑的猜测。 二、交换机控制软件的组成 (一)背景 1、交换机有很多的RJ45水晶头端口。 2、每个端口支持同时发送和接收字节数据。 3、每个端口接收的数据需要查表后才能转发给目标端口。 (二)端口状态扫描线程 负责扫描每个端口的状态&#x…

Part1:基于国内源完成Kubernetes集群部署

集群规划 操作系统&#xff1a;CentOS7 内核版本&#xff1a;5.4&#xff08;需升级&#xff09; 组件版本说明操作系统内核5.4RPM方式升级docker26.1.4yum安装cri-docker0.3.16二进制安装kubeadm1.30.11yum安装kubealet1.30.11yum安装kubectl1.30.11yum安装kubectl1.30.11yu…

中考英语之10难点单词

A abandon ~动词&#xff0c;意为 “抛弃&#xff1b;放弃”。 ~例如 He abandoned his old bike by the roadside.&#xff08;他把他的旧自行车扔在路边。&#xff09; absolute ~形容词&#xff0c;“绝对的&#xff1b;完全的”。 ~例如 We have absolute trust in him…

【GPT入门】第24课 langfuse介绍

【GPT入门】第24课 langfuse介绍 1. langfuse概念与作用2. 代码3. 页面效果4. 设计模式1. 装饰器模式2. 上下文管理模式1. langfuse概念与作用 Langfuse是一款专为大规模语言模型(LLM)应用开发设计的开源平台。其作用主要包括以下几个方面: 提升开发效率:通过消除LLM应用构…

在 React 中使用 Web Components 的实践操作

前言 在现代前端开发中&#xff0c;React 和 Web Components 都是广泛使用且备受欢迎的技术。React 是一个用于构建用户界面的 JavaScript 库&#xff0c;提供了组件化的开发方式和高效的状态管理&#xff0c;而 Web Components 是一套原生的浏览器技术标准&#xff0c;允许开…

C++单例模式精解

单例模式&#xff08;重点*&#xff09; 单例模式是23种常用设计模式中最简单的设计模式之一&#xff0c;它提供了一种创建对象的方式&#xff0c;确保只有单个对象被创建。这个设计模式主要目的是想在整个系统中只能出现类的一个实例&#xff0c;即一个类只有一个对象。 将单…

【微服务】java中http调用组件深入实战详解

目录 一、前言 二、http调用概述 2.1 什么是http调用 2.1.1 http调用步骤 2.2 HTTP调用特点 2.3 HTTP调用应用场景 三、微服务场景下http调用概述 3.1 微服务开发中http调用场景 3.2 微服务组件中http的应用 四、常用的http调用组件 4.1 java中常用的http组件介绍 4…

Implementing SAP BPC Embedded - 2nd Edition

Implementing SAP BPC Embedded - 2nd Edition

stm32第四天控制蜂鸣器

一&#xff1a; 1.蜂鸣器的种类 蜂鸣器是一种常用的电子发声元器件&#xff0c;采用直流电压供电。广泛应用于计算机&#xff0c;打ED机&#xff0c;报警器&#xff0c;电子玩具&#xff0c;汽车电子设备灯等产品中常见的蜂鸣器可分为有源蜂鸣器和无源蜂鸣器。 2.蜂鸣器的控制…

Swift 中 associatedtype 的用法详解

目录 前言 1.什么是associatedtype 2.associatedtype 的作用 1.让协议支持泛型 2.让协议支持不同的数据类型 3.结合 where 关键字限制类型 4.什么时候使用 associatedtype 5.总结 前言 在 Swift 语言中&#xff0c;泛型&#xff08;Generics&#xff09;是一个非常强大…

每日Attention学习26——Dynamic Weighted Feature Fusion

模块出处 [ACM MM 23] [link] [code] Efficient Parallel Multi-Scale Detail and Semantic Encoding Network for Lightweight Semantic Segmentation 模块名称 Dynamic Weighted Feature Fusion (DWFF) 模块作用 双级特征融合 模块结构 模块思想 我们提出了 DWFF 策略&am…

OpenCV实现图像特征提取与匹配

‌一、特征检测与描述子提取‌ ‌选择特征检测器‌ 常用算法包括&#xff1a; ‌ORB‌&#xff1a;一种高效的替代SIFT和SURF的算法&#xff0c;主要用于移动机器人和增强现实等领域。适合实时应用&#xff0c;结合FAST关键点与BRIEF描述子‌。‌SIFT&#xff08;尺度不变特征变…

向量检索在AI中的应用与技术解析

关键要点 向量检索在AI中用于信息检索、推荐系统和图像搜索&#xff0c;研究表明其通过高维空间中的向量表示数据来提升搜索相关性。它依赖于嵌入技术&#xff08;如Word2Vec、BERT&#xff09;和近邻算法&#xff08;如kNN、ANN&#xff09;&#xff0c;证据倾向于其在处理大…

事务与异步方法(@Async)协同工作

目录 1. 问题场景与风险 &#xff08;1&#xff09;典型场景 &#xff08;2&#xff09;风险分析 2. 解决方案&#xff1a;事务提交后触发异步操作 &#xff08;1&#xff09;代码示例 &#xff08;2&#xff09;关键注解 3. 原理解析 &#xff08;1&#xff09;事务同…

关于进程的实验(子进程和父进程相关的)

文章目录 1.第一个问题2.第二个问题3.第三个问题 1.第一个问题 编写一段程序&#xff0c;利用系统调用fork( )创建两个进程。当此程序运行时&#xff0c;在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符&#xff1a;父进程显示字符“a”;子进程分别显…

MyBatis 如何创建 SqlSession 对象的?

MyBatis 创建 SqlSession 对象的过程主要由 SqlSessionFactory 接口及其实现类来完成。以下是详细步骤&#xff1a; 1. SqlSessionFactory 接口: SqlSessionFactory 是 MyBatis 的核心接口之一&#xff0c;它负责创建 SqlSession 对象。 你可以将 SqlSessionFactory 视为 Sql…