C#核心技术---Linq

ops/2025/1/12 18:57:03/

目录

Linq介绍

Linq查询

语句查询

Linq扩展方法


 

Linq介绍

LINQ(读音link)——语言集成查询(Language Integrated Query),是.NET框架的扩展,一系列直接将查询功能集成到 C# 语言的技术统称,是一种使用类似SQL语句操作多种数据源的功能。

使用Linq,你可以从access数据库、程序对象的集合以及XML文档以及实现了IEnumerable或IEnumerable接口的集合类中查询数据。从.net framework3.5中开始引入,能够提升程序数据处理能力和开发效率,具有集成性、统一性、可扩展性、抽象性、说明式编程、可组成型、可转换性等优势。

Linq提供的程序

  • Linq to Object。提供程序查询内存中的集合和数组。
  • Linq to DataSet。提供程序查询ADO.NET数据集中的数据。
  • Linq to SQL。提供程序查询和修改Sql Server数据库中的数据,将应用程序中的对象模型映射到数据库表。
  • Linq to Entities。使用linq to entities时,会在后台将linq语句转换为sql语句与数据库交互,并能提供数据变化追踪。
  • Linq to XML。提供程序查询和修改XML,既能修改内存中的xml,也可以修改从文件中加载的。

Linq查询

Linq查询包括两种方式:

一、语句查询,

二、方法查询。

语句查询使用较多,也更容易理解,微软官网推荐使用。

语句查询

查询语法:

from 迭代变量  in 数据源  where ....   select 迭代变量
 //查询遍历数组//1.数据源int[] nums = { 12, 34, 9, 45, 52, 99, 76, 120 };//2.创建查询var numQuery = from m in numsselect m;//3.执行查询foreach ( var m in numQuery){Console.WriteLine(m);}

查询表达式在循环访问查询变量时(如上述示例中foreach),才会执行。

select子句,基于查询结果返回需要的值或字段,并能够对返回值指定类型。

  List<ItemInfo> itemInfos = GetItemList();//获取所有的名目列表//通过select返回列表中的所有名称属性值var items=from item in itemInfos select item.ItemName;foreach (var item in itemList01){Console.WriteLine(item.Id+","+item.Name);}//通过select指定返回的类型var itemList01 = from item in listselect new{ //匿名类型Id = item.ItemId,Name = item.ItemName};foreach (var item in itemList01){Console.WriteLine(item.Id+","+item.Name);}

where子句:用来指定筛选的条件,与sql查询语句中的where功能一样。通过where子句获取到满足条件的结果.

var itemList01 = from item in listwhere item.ItemId>102select item.ItemName;foreach (var item in itemList02){Console.WriteLine(item);}

orderby:用来排序,与sql中orderby的功能相同,使得返回结果可以根据某字段或某种规则实现升序或降序排列。

linq中语句默认展示为升序,降序使用【orderby 表达式 descending】

 var itemList3 = from item in listwhere item.ItemId > 102orderby item.ItemId descendingselect item.ItemName;foreach (var item in itemList3){Console.WriteLine(item);}

group by子句:用来对查询结果进行分组。且未指定key的情况下,key取值默认是true和false。如果分为多组,获取数据结果时需要手动遍历key获取对应的value

   List<IncomeInfo> incomeList = new List<IncomeInfo>(){new IncomeInfo(){IncomeId=1,IncomeName="收入1",ItemId=101},new IncomeInfo(){IncomeId=2,IncomeName="收入2",ItemId=101},new IncomeInfo(){IncomeId=3,IncomeName="收入3",ItemId=103},new IncomeInfo(){IncomeId=4,IncomeName="收入4",ItemId=102},new IncomeInfo(){IncomeId=5,IncomeName="收入5",ItemId=103},new IncomeInfo(){IncomeId=6,IncomeName="收入6",ItemId=104},new IncomeInfo(){IncomeId=7,IncomeName="收入7",ItemId=102},new IncomeInfo(){IncomeId=8,IncomeName="收入8",ItemId=105},new IncomeInfo(){IncomeId=9,IncomeName="收入9",ItemId=104},new IncomeInfo(){IncomeId=10,IncomeName="收入10",ItemId=106}};//把收入记录信息按ItemId分组var incomeList1 = from income in incomeList group income by income.ItemId;//分组打印foreach(var income in incomeList1){Console.WriteLine(income.Key);foreach(var item in income){Console.WriteLine(item.ItemId +"--"+item.IncomeName);}Console.WriteLine();}
//输出结果:
101
101--收入1
101--收入2103
103--收入3
103--收入5102
102--收入4
102--收入7104
104--收入6
104--收入9105
105--收入8106
106--收入10

Join子句:用于联合查询,一般会存在两个数据源,且两个数据源中有相同的字段可进行比较。使用格式为【join 数据 in 数据源1 on key1 equals key2】

//inner join 只匹配能匹配上的
var incomeList2 = from item in listjoin income in incomeList on item.ItemId equals income.ItemIdselect new{ItemId = item.ItemId,ItemName = item.ItemName,IncomeId = income.IncomeId,Income = income.IncomeName};
foreach (var item in incomeList2)
{Console.WriteLine($"名目编号:{item.ItemId}, 名目:{item.ItemName},  收入编号:{item.IncomeId},  收入名称:{item.Income}");
}//left join 能左边为准,右边匹配不上的,就是null
var incomeList3= from income in incomeListjoin item in list on income.ItemId equals item.ItemIdinto ItemsNewfrom newItem in ItemsNew.DefaultIfEmpty() //如果序列为空就为默认值select new{IncomeId = income.IncomeId,Income = income.IncomeName,ItemName = newItem == null ? "无名目" : newItem.ItemName};
foreach (var item in incomeList3)
{Console.WriteLine($" 收入编号:{item.IncomeId},  收入名称:{item.Income}, 名目:{item.ItemName}");
}//输出:收入编号:1,  收入名称:收入1, 名目:银行转账收入编号:2,  收入名称:收入2, 名目:银行转账收入编号:3,  收入名称:收入3, 名目:无名目收入编号:4,  收入名称:收入4, 名目:股票收入收入编号:5,  收入名称:收入5, 名目:无名目收入编号:6,  收入名称:收入6, 名目:工资发放收入编号:7,  收入名称:收入7, 名目:股票收入收入编号:8,  收入名称:收入8, 名目:朋友还钱收入编号:9,  收入名称:收入9, 名目:工资发放收入编号:10,  收入名称:收入10, 名目:无名目//right join 以右边为准,左边匹配不上的,就是nullvar incomeList4 = from item in listjoin income in incomeList on item.ItemId equals income.ItemIdinto incomesNew  //符合条件的收入列表from newIncome in incomesNew.DefaultIfEmpty() //如果序列为空就为默认值select new{IncomeId = newIncome == null ? 0 : newIncome.IncomeId,Income = newIncome == null ? "无":newIncome.IncomeName,ItemName = item.ItemName};foreach (var item in incomeList4){Console.WriteLine($"名目:{item.ItemName} , 收入编号:{item.IncomeId},  收入名称:{item.Income}");}
收入编号:1,  收入名称:收入1,名目:银行转账
收入编号:2,  收入名称:收入2,名目:银行转账
收入编号:4,  收入名称:收入4,名目:股票收入
收入编号:7,  收入名称:收入7,名目:股票收入
收入编号:0,  收入名称:无,   名目:客户付款
收入编号:6,  收入名称:收入6,名目:工资发放
收入编号:9,  收入名称:收入9,名目:工资发放
收入编号:8,  收入名称:收入8,名目:朋友还钱

Linq扩展方法

Linq查询中,为了更加清晰明了的阅读,我们一般采用查询语法,但有些查询操作没有等效的查询表达式,只能采用方法查询,即调用内部方法,有些场景中也可以将查询语法和方法语法结合使用。

int[] nums = { 12, 34, 9, 45, 52, 99, 76, 120 };
var queryList=from num in nums select num;
var avg=queryList.Average();//求平均
var max=queryList.Max();//求最大值
var min=queryList.Min();//求最小值
var newList=queryList.OrderBy(n=>n);var numList1=nums.Where(num=>num>40);var itemList4 = list.Where(item => item.ItemId > 103);//链式写法 Where().OrderBy().Select()....var itemList5 = list.Where(item => item.ItemId > 102).OrderByDescending(item=>item.ItemId).Select(item =>      new{Id = item.ItemId,Name = item.ItemName});//Distinct/First/Findvar nums2=  nums1.Distinct();//去重ItemInfo item1=list.OrderBy(item=>item.ItemId).First();//返回第一个元素 若集合为空,会异常ItemInfo item2 = list.OrderBy(item => item.ItemId).FirstOrDefault();//返回第一个元素 若集合为空,返回默认值int maxId=list.Max(item=>item.ItemId);int minId=list.Min(item=>item.ItemId);int count = nums1.Distinct().Count();//获取集合总元素数var itemList6 = list.Where(item => item.ItemId > 101);var itemList7 = itemList6.Union(itemList4);//合并成一个集合,去重var itemList8 = itemList6.Concat(itemList4);//合并成一个集合,不去重var itemList9 = itemList6.Except(itemList4);//得到一个差集,去掉公共的部分//Skip/Take  跳过指定数目的元素/连续取指定数目的元素var itemList10 = list.Skip(2).Take(3);//Join 连接两个集合,关联属性,合并一个集合,包含两个集合中的信息  inner joinvar incomeList7 = list.Join(incomeList, item => item.ItemId, income => income.ItemId, (item, income) => new{ItemId = item.ItemId,ItemName = item.ItemName,Id = income.ItemId,Income = income.IncomeName});foreach (var item in incomeList7){Console.WriteLine($"名目编号:{item.ItemId}, 名目:{item.ItemName},  收入编号:{item.Id},  收入名称:{item.Income}");}//分组 var incomeList8 = incomeList.GroupBy(income => income.ItemId);foreach(var item in incomeList8){Console.WriteLine(item.Key);foreach(var it in item){Console.WriteLine(it.IncomeId + "," + it.IncomeName);}}//GroupJoin ---等同性将两个序列的元素进行关联,并对结果进行分组。var groups = list.GroupJoin(incomeList, item => item.ItemId, income => income.ItemId, (item, income) => new{ItemId = item.ItemId,ItemName = item.ItemName,Records = income.Select(r => new { Id = r.IncomeId, Income = r.IncomeName })}) ;foreach(var item in groups){Console.WriteLine(item.ItemId+","+item.ItemName);foreach(var r in item.Records){Console.WriteLine("编号:"+r.Id+" , 名称:"+r.Income);}}

http://www.ppmy.cn/ops/149080.html

相关文章

基于单片机的空调温度测试测控系统设计

摘 要 : 单片机在测试测控系统中占据着重要的地位 , 本文以 AT89C51 单片机为基础 , 进行了空调温度测试测控系统的设计, 分析了其硬件设计组成及软件功能实现 , 旨在为空调温度测试测控系统的相关研究和设计实践提供参考. 关键词 : 单片机 ; 空调温度 ; 测试测控系…

Spark是什么?Flink和Spark区别

Spark是什么&#xff1f;Flink和Spark区别 一、Spark二、Spark和Flink区别三、总结 一、Spark Apache Spark 是一个开源的大数据处理框架&#xff0c;主要用于大规模数据处理和分析。它支持多种数据处理模式&#xff0c;包括批处理、流处理、SQL 查询、机器学习和图处理等。 核…

长上下文窗口的大语言模型数据设计

长上下文窗口的大语言模型数据设计 第一部分&#xff1a;引言 随着大语言模型&#xff08;LLMs&#xff09;的广泛应用及其日益成长的复杂性&#xff0c;处理长文本内容已成为研究者和开发者面临的重要挑战。长上下文窗口的设计尤为关键&#xff0c;决定了模型能否高效处理长…

岭南师范学院携手泰迪智能科技共建研究生联合培养基地

1月6日&#xff0c;岭南师范学院数学与统计学院栾姝院长、统计系赵海清主任、信息与计算科学系刘雄副主任&#xff0c;教学督导潘立军教授莅临广东泰迪智能科技股份有限公司产教融合实训中心开展“泰迪智能科技岭南师范学院研究生联合培养基地”战略合作签约仪式。泰迪智能科技…

丢帧常见的几种处理方法

1. 优化硬件配置 • 升级计算机硬件&#xff0c;如增加内存、使用更高速的 CPU 和存储设备&#xff0c;以提高数据处理和传输能力。• 确保相机与计算机之间的连接稳定&#xff0c;如使用高质量的数据线、合适的接口卡&#xff0c;并检查接口是否松动。 2. 调整相机参数 • 降低…

uniApp 在真机环境下报错:包时未添加cemera模块,请参考https://ask.dcloud.net.cn/article/283

文章目录 问题分析 问题 uniApp 在真机环境下报错&#xff1a;包时未添加cemera模块&#xff0c;请参考https://ask.dcloud.net.cn/article/283 分析 打开提示的网址&#xff1a;https://ask.dcloud.net.cn/article/283&#xff0c;根据网址中的提示我们配置打包时的环境

Unigui基于vue+elementui的自研框架

一、前言 笔者由于近期遇到一个项目&#xff0c;其基础数据维护功能的数据项较多、开发效率、周期都较长&#xff0c;当时考虑项目周期、项目稳定性情况&#xff08;部分版本在基础类继承以及处理存在部分bug&#xff09;下、功能不具备通用性&#xff0c;采用原始的每项功能单…

Vue.js 基础过渡 动画

本帖我们主要讨论 Vue.js 的过渡效果与动画效果。 过渡 Vue 在插入、更新或者移除 DOM 时&#xff0c;提供多种不同方式的应用过渡效果。 Vue 提供了内置的过渡封装组件&#xff0c;该组件用于包裹要实现过渡效果的组件。 语法格式 <transition name "nameoftran…