【.NET Core】语言集成查询(LINQ)详解

【.NET Core】语言集成查询(LINQ)详解

文章目录

  • 【.NET Core】语言集成查询(LINQ)详解
    • 一、概述
    • 二、查询表达式
    • 三、LINQ查询操作中的类型关系
      • 3.1 不转换数据源的查询
      • 3.2 转换数据源的查询
      • 3.3 转换数据源返回复杂类型查询
      • 3.4 让编译器推断类型信息
    • 四、LINQ查询中的IEnumberable<T>变量
      • 4.1 IEnumerator
      • 4.2 IEnumberable
      • 4.3 Queryable
      • 4.4 Queryable VS IEnumberable

一、概述

语言集成查询(LINQ)是一系列直接将查询功能集成到C#语言的技术统称。数据查询历来都表示为简单的字符串,没有编译时类型检查或IntelliSense支持,此外,需要针对每种类型的数据源了解不同的查询语言:SQL数据库,XML文档,各种Web服务类。借助LINQ,查询成为了最高级别的语言构造。

IntelliSense是一种代码补全辅助工具,它包含许多功能;成员列表,参数信息,快速信息和完成单词。使用这些功能,可以详细了解使用的代码,跟踪键入的参数,还可通过轻敲几个按键来添加属性和方法调用。

对于每个程序员来数,LINQ是一种"语言集成"查询表达式。查询表达式采用声明性查询语法编写而成。使用查询语法,可以用最少的代码对数据源执行筛选,排序和分组操作。可使用相同的基本查询表达式模式来查询和转换SQL数据库,ADO.NET数据集,XML文档和流以及.NET集合中的数据。

二、查询表达式

  • 查询表达式可用于查询并转换所有启用了LINQ的数据源中的数据。
  • 查询表达式使用C#语言构造,因此查询它易于掌握。
  • 查询表达式中的变量全都是强类型。
  • 只有在循环访问查询变量后,才会执行查询。
  • 查询表达式在编译时,根据C#规范规则转成标准的查询运算符方法调用。可使用查询语法表示的任何查询都可以使用方法进行表示。查询语法的可读性更高,更简洁。
  • 在编写LINQ查询时尽量使用查询语法,并在必要时尽可能使用方法语法。
  • 查询操作(如Count或Max)没有等效的查询表达式子句,必须表示为方法调用。
  • 查询表达式在编译时会根据类型,编译为表达式树或委托。IEnumerable查询编译为委托。IQueryable和IQueryable查询编译为表达式树。

三、LINQ查询操作中的类型关系

LINQ 查询操作在数据源、查询本身及查询执行中是强类型的。 查询中变量的类型必须与数据源中元素的类型和 foreach 语句中迭代变量的类型兼容。

3.1 不转换数据源的查询

List<string> names=new List<string>{"John","Rick","Maggie","Mary"};
IEnumerable<string> respQuery = from name in names where name[0]=='M' select name;
foreach(string str in respQuery){Console.WriteLine(str);
}
  1. 数据源的类型参数决定范围变量的类型。
  2. 所选对象的类型决定查询变量的类型。如上例子name是一个字符串。因此查询变量就是一个IEnumerable。
  3. 在foreach语句中循环访问查询变量。因为查询变量是一个字符串序列,所以迭代变量也是一个字符串。

3.2 转换数据源的查询

Table<Cusomer> customers = db.GetTable<Customer>();
IQueryable<string> custNameQuery = from customer in customers where cust.City=="ShangHai"select customer.Name;
foreach(string str in custNameQuery){Console.WriteLine(str);
}
  1. 数据源的类型参数决定范围变量的类型。
  2. select语句返回Name属性,而非完整的Customer对象。因为Name是一个字符串,所以custNameQuery的类型参数是string,而非Customer。
  3. custNameQuery是一个字符串序列,所以foreach循环的迭代变量也必须是string。

3.3 转换数据源返回复杂类型查询

Table<Cusomer> customers = db.GetTable<Customer>();
IQueryable<string> custNameQuery = from customer in customers where cust.City=="ShangHai"select  new {custName  = customer.Name,custPhone = customer.Phone};
foreach(var cust in custNameQuery){Console.WriteLine(cust.Phone);
}
  1. 数据源的类型参数始终为查询中范围变量的类型。
  2. 因为 select 语句生成匿名类型,所以必须使用 var 隐式类型化查询变量。
  3. 因为查询变量的类型是隐式的,所以 foreach 循环中的迭代变量也必须是隐式的。

3.4 让编译器推断类型信息

var Customers = db.GetTable<Customers>();
var custQuery = from cust  in Customers where cust.City == "London" select cust
foreach(var item in custQuery){Console.WriteLine(item);
}

上面实例使用关键字var可用于查询操作中的任何本地变量,编译器为查询操作中的各个变量提供强类型。

四、LINQ查询中的IEnumberable变量

LINQ查询变量被类型化为IEnumberable或派生类型(IQueryable)。看到类型化为IEnumberable的查询变量时,意味着执行查询时,该查询将生成包含零个或多个T类型对象的序列。

IEnumberable<User> userQuery = from user in users where user.name="goyeer" select user;

4.1 IEnumerator

IEnumberator对象是一个真正的集合访问器,如果没它就不能使用foreach语句遍历集合或数组,因为只有有了IEnumberator对象才能访问集合中的项,假如没有它连集合中的项都访问不了。

public class MyClass : IEnumerable
{int[] temp = { 1, 32, 43, 343 };public IEnumerator GetEnumerator(){return temp.GetEnumerator();}
}public class Program
{public static void Main(String[] args){MyClass temp = new MyClass();foreach (int node in temp) {Debug.WriteLine(node);}} 
}

IEnumberator是所有非枚举型枚举器的基接口,其泛型等效是System.Collections.Generic.IEnumerator<T>接口。

枚举器可用于读取集合中的数据,但不能用于修改基础集合。枚举初始化时,定位在集合中第一个元素的前面。在读取的值Current之前,必须调用MoveNext方法以将枚举数推进到集合的第一个元素;否则为Current未定义。

在调用Current或MoveNext之前,Reset返回同一对象。MoveNext将Current设置为下一个元素。

如果MoveNext传递集合的末尾,则枚举器位于集合中最后一个元素之后,并MoveNext返回false。当枚举器位于此位置时,对MoveNext的后续调用也会返回false。如果最后一次MoveNext调用返回false,此时Current则为未定定义。

属性

  • Current = 获取集合中位于枚举数当前位置的元素

方法

  • MoveNext() 将枚举数推进到集合的下一个元素。
  • Reset() 将枚举数设置为其初始位置,该位置位于集合中第一个元素之前。

4.2 IEnumberable

IEnumberable是一个可枚举的所有非泛型集合的基础接口。IEnumberable包含单个方法GetEnumberator;IEnumerable接口为foreach迭代提供了支持。

IEnumerator接口定义对类中的集合类型对象的迭代方式。

IEnumerable接口允许使用foreach循环进行枚举。

4.3 Queryable

提供一组用于查询实现IQueryable的数据结构static方法。类中Queryable声明的方法集提供了标准查询运算的实现,用于查询IQueryable的数据源标准查询运算符是LINQ模式的常规用途方法,使你能够对任何中的数据表进行遍历,筛选和投影操作。

4.4 Queryable VS IEnumberable

  • System.linq.Queryable中,参数接收的是一个表达式类型,返回IQueryable接口

  • System.linq.Enumerable中,参数接收的是一个谓词表达式,也就是一个委托

  • Func<>谓词表达式,就是一个委托,委托一旦调用,就立即执行了,将执行结果保存在内存中

  • Expression是一个表达式,会存储拼接表达式树,直到在运行期最终执行。

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

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

相关文章

微调Fine tune

网络架构 一个神经网络一般可以分为两块 特征抽取将原始像素变成容易线性分割的特征线性分类器来做分类 微调&#xff1a;使用之前已经训练好的特征抽取模块来直接使用到现有模型上&#xff0c;而对于线性分类器由于标号可能发生改变而不能直接使用 训练 是一个目标数据集上…

道可云元宇宙每日资讯|智慧旅游发展大会暨智慧旅游示范展示活动在南京举办

道可云元宇宙每日简报&#xff08;2023年11月28日&#xff09;讯&#xff0c;今日元宇宙新鲜事有&#xff1a; 智慧旅游发展大会暨智慧旅游示范展示活动在南京举办 2023年11月23日至25日&#xff0c;由文化和旅游部资源开发司、江苏省文化和旅游厅共同主办的“智慧旅游发展大会…

Linux驱动开发——网络设备驱动(实战篇)

目录 四、 网络设备驱动实例 五、DM9000 网络设备驱动代码分析 六、NAPI 七、习题 书接上回&#xff1a; Linux驱动开发——网络设备驱动&#xff08;理论篇&#xff09;-CSDN博客 &#xff08;没看过上面博客的同学&#xff0c;skb是linux对于网络套接字缓冲区的一个虚拟…

Leetcode 136. 只出现一次的数字

class Solution {//任何数与0异或结果都是原来的数//任何数和自身异或结果都是0//异或满足交换律和结合律//a ^ b ^ a (a ^ a) ^ b 0 ^ b bpublic int singleNumber(int[] nums) {int res nums[0];for(int i 1; i < nums.length; i){res ^ nums[i];}return res;} }

OpenCvSharp从入门到实践-(04)色彩空间

目录 1、GRAY色彩空间 2、从BGR色彩空间转换到GRAY色彩空间 2.1色彩空间转换码 2.2实例 BGR色彩空间转换到GRAY色彩空间 3、HSV色彩空间 4、从BGR色彩空间转换到HSV色彩空间 4.1色彩空间转换码 4.2实例 BGR色彩空间转换到HSV色彩空间 1、GRAY色彩空间 GRAY色彩空间通常…

26、Spring是如何解决Bean的循环依赖?

Spring是如何解决Bean的循环依赖&#xff1f; 采用三级缓存解决的 就是三个Map &#xff1b; 关键&#xff1a; 一定要有一个缓存保存它的早期对象作为死循环的出口 一级缓存&#xff1a;存储完整的Bean二级缓存&#xff1a; 避免多重循环依赖的情况 重复创建动态代理。三级缓…

Spring简单的存储和读取

前言 前面讲了spring的创建&#xff0c;现在说说关于Bean和五大类注解 一、Bean是什么&#xff1f; 在 Java 语⾔中对象也叫做 Bean&#xff0c;所以后⾯咱们再遇到对象就以 Bean 著称。这篇文章还是以spring创建为主。 二、存储对象 2.1 俩种存储方式 需要在 spring-conf…

FlinkSql-Temporal Joins-Lookup Join

说明 在 Flink SQL 中&#xff0c;Temporal Joins 是一种常见的数据关联操作&#xff0c;特别适用于处理包含时间维度的数据。Lookup Join 是 Temporal Joins 的一种类型&#xff0c;它允许将流数据与维表数据进行关联。使用场景如下&#xff1a; 实时维度关联&#xff1a; 当…

Python---文件备份案例

需求&#xff1a;用户输入当前目录下任意文件名&#xff0c;完成对该文件的备份功能(备份文件名为xx[备份]后缀&#xff0c;例如&#xff1a;test[备份].txt)。 思考&#xff1a; ① 接收用户输入的文件名 ② 规划备份文件名 ③ 备份文件写入数据 代码 # 1、接收用户输入的…

paddle detection整体结构

核心思想就是通过Yaml文件将主体模块和可拔插的模块组成一个完整的pipline. train.py流程解析&#xff1a; 初始化训练参数 1 parserArgsParser() #读取命令行传递参数&#xff0c;加载yaml文件参数 2 整合参数&#xff0c;检查参数配置是否正确 3 检查是否使用GPU加速 4 检查…

Ubuntu 18.04 ARM离线安装cifs-utils

1、环境说明 由于本地都是x86&#xff0c;不支持arm架构&#xff0c;所以用Docker容器下载离线包本地环境&#xff1a;Docker、Ubuntu 22.04.1 LTS x86&#xff08;可上网&#xff09;安装环境&#xff1a;Ubuntu 18.04.4 LTS arm&#xff08;内网&#xff09; 2、启动qemu-a…

使用Jmeter进行http接口性能测试

在进行网页或应用程序后台接口开发时&#xff0c;一般要及时测试开发的接口能否正确接收和返回数据&#xff0c;对于单次测试&#xff0c;Postman插件是个不错的Http请求模拟工具。 但是Postman只能模拟单客户端的单次请求&#xff0c;而对于模拟多用户并发等性能测试&#xf…

[Verilog语法]:===和!==运算符使用注意事项

[Verilog语法]&#xff1a;和!运算符使用注意事项 1&#xff0c; 和 !运算符使用注意事项2&#xff0c;3&#xff0c; 1&#xff0c; 和 !运算符使用注意事项 参考文献&#xff1a; 1&#xff0c;[SystemVerilog语法拾遗] 和!运算符使用注意事项 2&#xff0c; 3&#xff0c;

机器学习入门(第五天)——决策树(每次选一边)

Decision tree 知识树 Knowledge tree 一个小故事 A story 挑苹果&#xff1a; 根据这些特征&#xff0c;如颜色是否是红色、硬度是否是硬、香味是否是香&#xff0c;如果全部满足绝对是好苹果&#xff0c;或者红色硬但是无味也是好苹果&#xff0c;从上图可以看出来&#…

数据可视化:用图表和图形展示数据

写在开头 在当今信息爆炸的时代,海量的数据如同一座沉默的宝库,等待着我们挖掘和理解。然而,这些庞大的数据集本身可能令人望而生畏。在这个时候,数据可视化成为了解数据、发现模式和传达信息的强大工具。本篇博客将带领你探索数据可视化的奇妙世界,学习如何在python中使…

91基于matlab的以GUI实现指纹的识别和匹配百分比

基于matlab的以GUI实现指纹的识别和匹配百分比,中间有对指纹的二值化&#xff0c;M连接&#xff0c;特征提取等处理功能。数据可更换自己的&#xff0c;程序已调通&#xff0c;可直接运行。 91M连接 特征提取 (xiaohongshu.com)

Windows 安装redis,设置开机自启动

Windows 安装redis,设置开机自启动 文章目录 Windows 安装redis,设置开机自启动下载, 解压到指定目录设置redis密码启动redis服务端停止redis服务端设置自启动 下载, 解压到指定目录 官网地址: https://redis.io/ 安装包下载地址: https://github.com/tporadowski/redis/relea…

NB-IoT BC260Y Open CPU SDK⑥ADC的应用

NB-IoT BC260Y Open CPU SDK⑥ADC的应用 1、BC260Y_CN_AA模块 ADC的介绍2、ADC相关API的介绍3、软件设计4、实例分析5、以下是调试的结果:1、BC260Y_CN_AA模块 ADC的介绍 BC260Y-CN QuecOpen 模块提供 2 个专用于 ADC(ADC0、ADC1)功能的 I/O 引脚。通过相应的 API函数可以直…

掌握Vue侦听器(watch)的应用

文章目录 &#x1f341;watch 的优缺点&#x1f342;Watch 优点&#x1f342;Watch 缺点 &#x1f341;watch 的用法&#x1f342;对象式 watch&#x1f342;函数式 watch &#x1f341;代码示例&#x1f342;监听基本数据类型&#x1f342;监听复杂数据类型&#xff08;Object…

GPLT(有空就写)

L2 - 047 锦标赛 思路&#xff1a; 将其放入一颗满二叉树上去考虑&#xff1a;从二叉树的最底层开始&#xff0c;每一轮比赛&#xff0c;为同一个祖先的左右两个儿子进行比较&#xff0c;而你需要将败者的能力值填到左右两个儿子其中一个上面&#xff0c;另一个就向上传递表示胜…