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

news/2024/5/19 23:24:27 标签: .netcore, linq, c#

【.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 转换数据源的查询

c#">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 让编译器推断类型信息

c#">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类型对象的序列。

c#">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.niftyadmin.cn/n/5237151.html

相关文章

NIO--07--Java lO模型详解

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 何为 IO?先从计算机结构的角度来解读一下I/o.再从应用程序的角度来解读一下I/O 阻塞/非阻塞/同步/异步IO阻塞IO非阻塞IO异步IO举例 Java中3种常见的IO模型BIO (Blo…

【PyTorch】概述

文章目录 1. PyTorch是什么&#xff1f;2. PyTorch的特点3. PyTorch的架构 1. PyTorch是什么&#xff1f; PyTorch是一个深度学习框架&#xff0c;由Facebook于2016年开源发布。PyTorch是基于Torch框架的Python接口&#xff0c;旨在提供易用的强大工具来进行神经网络的构建和训…

[Unity数据管理]自定义菜单创建Unity内部数据表(ScriptableObject)

Unity 在开发的时候如果数据量比较大&#xff0c;或者一部分数据需要存在云端&#xff0c;那么就需要一些数据库 轻量型到大型的包括&#xff1a; 数组-内存存储读取 列表-内存存储读取 List<T> tList new List<T>(); XML-硬盘存储读取 JSON-硬盘存储读取 …

bfs P2895 [USACO08FEB] Meteor Shower S

[P2895 USACO08FEB] Meteor Shower S - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) bfs。难点在于处理走到该点时的时间与该处陨石降落的时间的比较。 可以发现&#xff0c;在某处可能有多个陨石降落&#xff0c;但是此题只考虑陨石降落的最小时间。因此&#xff0c;我们可…

分享86个焦点幻灯JS特效,总有一款适合您

分享86个焦点幻灯JS特效&#xff0c;总有一款适合您 86个焦点幻灯JS特效下载链接&#xff1a;https://pan.baidu.com/s/1Gm2jwN_AAF9QjFzQ9bCM_g?pwd6666 提取码&#xff1a;6666 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 学习知识费力气&#xff0c;…

使用栈解决括号匹配问题(详解)

项目结构 项目头文件的代码或截图 头文件代码 #ifndef LINKSTACK_H #define LINKSTACK_H #include <stdio.h> #include <stdlib.h> // 链式栈的节点 typedef struct LINKNODE {struct LINKNODE* next; }LinkNode; // 链式栈 typedef struct LINKSTACK {LinkNode h…

数字化转型失败率为什么这么高?

引言 数字化转型已成为当今商业环境中的重要议题。它指的是企业通过采用数字技术&#xff0c;对业务流程、文化和客户体验进行全面变革&#xff0c;以适应数字化时代的需求和趋势。 然而&#xff0c;尽管数字化转型的重要性日益凸显&#xff0c;但令人担忧的是&#xff0c;许多…

Qt配置OpenCV(MSVC编译)

目录 1.准备工具 1.1 Qt&#xff1a;5.14.2 64位 1.2 Opencv&#xff1a;4.6.0 1.3 Visual Studio 2017 2. QtMSVC开发环境搭建 3. 配置环境变量 3.1 Opencv环境变量配置 4. Qt 代码测试 1.准备工具 1.1 Qt&#xff1a;5.14.2 64位 1.2 Opencv&#xff1a;4.6.0 官…