(十一)CSharp-LINQ-查询表达式(2)

news2024/9/16 20:33:53

一、查询表达式

1、查询表达式的结构

查询表达式由 from 子句和查询主体组成。

  • 子句必须按照一定的顺序出现。
  • from 子句和 select…group 子句这两部分是必需的。
  • 其他子句是可选的。
  • 在 LINQ 查询表达式中,select 子句在表达式最后。
  • 可以有任意多的 from…let…where 子句。

请添加图片描述

2、from 子句

from 子句指定了要作为数据源使用的数据集合。它还引入了迭代变量。

要点:

  • 1)迭代变量逐个表示数据源的每一个元素。

  • 2)from 子句的语法如下:

    • Type 是集合中元素的类型。这是可选的,因为编译器可以从集合中推断类型。
    • Item 是迭代变量的名字。
    • Items 是要查询的集合的名字。集合必须是可枚举的。
from Type Item in Items
//迭代变量声明:Type Item in Items
int arr1 = {10,11,12,13};

var query = from item in arr1
		    where item < 13
		    select item;

foreach(var item in query)
Console.Write($"{ item },");
//迭代变量:item

输出结果:

10,11,12,

图演示了 from 子句的语法

请添加图片描述

LINQ 的 from 子句和 foreach 语句非常相似,但主要的不同点如下:

  • foreach 语句命令式地制定了要从第一个到最后一个按顺序访问集合中的项。而 from 子句则声明式地规定集合中的每个项都要被访问,但并没有假定以什么样的顺序。

  • foreach 语句在遇到代码时就执行其主体,而 from 子句什么也不执行。它创建可以执行查询的后台代码对象。只有在程序的控制流遇到访问查询变量的语句时,才会执行查询。

3、join 子句

有关联结的要点:

  • 使用联结来结合两个或更多集合中的数据。
  • 联结操作接受两个集合,然后创建一个临时的对象集合,其中每一个对象包含两个原始集合对象中的所有字段。

联结的语法如下,它指定了第二个集合要和之前子句中的集合进行联结:

join Identifier in Collection2 on Field1 equals Field2
//关键字:join、in、on、equals
//指定另外的集合和 ID 来引用它:Identifier in Collection2
//用于比较相等性的字段:Field1 equals Field2

图20-4演示了 join 子句的语法:

请添加图片描述

join 子句的示例

var query = from s in students
			join c in studentsInCourses on s.StID equals c.StID

//第一个集合和 ID:from s in students
//第二集合和 ID:c in studentsInCourses
//第一个集合的项:s.StID
//第二集合的项:c.StID

什么是联结

LINQ 中的 join 接受两个集合,然后创建一个新的集合,其中每一个元素包含两个原始集合中的元素成员。

public class Student
{
public int StID;
public string LastName;
}

public class CourseStudent
{
public string CourseName;
public inr StID;
}

如图所示:
Student 对象为 students,CourseStudent 对象为 studentsInCourses。

请添加图片描述

*图20-6演示了联结是如何工作的。

如果我们拿第一个学生的记录并把它的 ID 和每一个 studentsInCourses 对象中的学生 ID 进行比较,可以找到两条匹配的记录,中间列的顶部就是。

请添加图片描述

示例:


    class Program
    {
        public class Student
        {
            public int StID;
            public string LastName;
        }

        public class CourseStudent
        {
            public string CourseName;
            public int StID;
        }

        static Student[] students = new Student[]
        {
            new Student { StID = 1, LastName = "Carson" },
            new Student { StID = 2, LastName = "Klassen" },
            new Student { StID = 3, LastName = "Fleming" },

        };

        static CourseStudent[] studentsInCourses = new CourseStudent[]
        {
            new CourseStudent { CourseName = "Art",     StID = 1 },
            new CourseStudent { CourseName = "Art",     StID = 2 },
            new CourseStudent { CourseName = "History",     StID = 1 },
            new CourseStudent { CourseName = "History",     StID = 3 },
            new CourseStudent { CourseName = "Physics",     StID = 3 },
        };

        static void Main(string[] args)
        {
            var query = from s in students
                        join c in studentsInCourses on s.StID equals c.StID
                        where c.CourseName == "History"
                        select s.LastName;

            foreach (var q in query)
                Console.WriteLine($"Student taking History: { q }");
                             
            Console.ReadKey();
        }
    }

输出结果:

Student taking History: Carson
Student taking History: Fleming

4、查询主体中的 from…let…where 片段

可选的 from…let…where 部分是查询主体的第一部分,可以由任意数量的3种子句构成—— from 子句、let 子句和 where 子句。

1)from 子句

查询表达式从必需的 from 子句开始,后面跟的是查询主体。主体本身可以从任何数量的其他 from 子句开始,每一个 from 子句都指定了一个额外的源数据集合并引入了要在之后运算的迭代变量。

请添加图片描述

示例:

      static void Main(string[] args)
        {
            var groupA = new[] { 3, 4, 5, 6 };
            var groupB = new[] { 6, 7, 8, 9 };

            var someInts = from a in groupA//必需的第一个 from 子句
                           from b in groupB//查询主体的第一个子句
                           where a > 4 && b <= 8
                           select new { a, b, sum = a + b };//匿名类型对象

            foreach (var x in someInts)
                Console.WriteLine(x);

            Console.ReadKey();
        }

输出结果:

{ a = 5, b = 6, sum = 11 }
{ a = 5, b = 7, sum = 12 }
{ a = 5, b = 8, sum = 13 }
{ a = 6, b = 6, sum = 12 }
{ a = 6, b = 7, sum = 13 }
{ a = 6, b = 8, sum = 14 }

2)let 子句

let 子句接受一个表达式的运算并且把它赋值给一个需要在其他运算种使用的标识符。

let 子句的语法如下:

let Identifier = Expression

示例:

static void Main(string[] args)
        {
            var groupA = new[] { 3, 4, 5, 6 };
            var groupB = new[] { 6, 7, 8, 9 };

            var someInts = from a in groupA
                           from b in groupB
                           let sum = a + b //在新的变量中保存结果
                           where sum == 12
                           select new { a, b, sum};

            foreach (var x in someInts)
                Console.WriteLine(x);

            Console.ReadKey();
        }

输出结果:

{ a = 3, b = 9, sum = 12 }
{ a = 4, b = 8, sum = 12 }
{ a = 5, b = 7, sum = 12 }
{ a = 6, b = 6, sum = 12 }

3)where 子句

==where 子句根据之后的运算来去除不符合指定条件的项目。==where 子句如下:

where BooleanExpression

有关 where的要点:

  • 只要是在 from…let…where 部分中,查询表达式可以有任意多个 where 子句。
  • 一个项必须满足所有 where 子句才能避免在之后被去除。
    static void Main(string[] args)
        {
            var groupA = new[] { 3, 4, 5, 6 };
            var groupB = new[] { 6, 7, 8, 9 };

            var someInts = from a in groupA
                           from b in groupB
                           let sum = a + b 
                           where sum >= 11//条件1
                           where a == 4 //条件2
                           select new { a, b, sum };

            foreach (var x in someInts)
                Console.WriteLine(x);

            Console.ReadKey();
        }

输出结果:

{ a = 4, b = 7, sum = 11 }
{ a = 4, b = 8, sum = 12 }
{ a = 4, b = 9, sum = 13 }

二、orderby 子句

orderby 子句接受一个表达式并根据表达式按顺序返回结果项

可选的 ascending 和 descending 关键字设置了排序方向。表达式通常是项的一个字段。该字段不一定非得是数值字段,也可以是字符串这样的可排序类型。

  • orderby 子句的默认排序是升序。然后,我们可以使用 ascending 和 descending 关键字显式地设置元素的排序为升序或降序
  • 可以有任意多个子句,它们必须使用逗号分隔。
       static void Main(string[] args)
        {
            var students = new[]
            {
              new { LName = "Jones", FName = "Mary" , Age = 19, Major = "History" },
              new { LName = "Smith", FName = "Bob" , Age = 20, Major = "CompSci" },
              new { LName = "Fleming", FName = "Carol" , Age = 21, Major = "History" },
          };

            var query = from student in students
                        orderby student.Age//根据年龄排序
                        select student;

            foreach (var s in query)
                Console.WriteLine($"{ s.LName },{ s.FName },{ s.Age },{ s.Major }");

            Console.ReadKey();
        }

输出结果:

Jones,Mary,19,History
Smith,Bob,20,CompSci
Fleming,Carol,21,History

三、select…group 子句

select…group 部分由两种类型的子句组成——select 子句和 group…by 子句。select…group 部分之前的子句指定了数据源和要选择的对象。

select…group 部分的功能如下:

  • 1)==select 子句指定应用选择所选对象的哪些部分。==它可以指定下面的任意一项。

    • 整个数据项。
    • 数据项的一个字段。
    • 数据项中几个字段组成的新对象。(或类似其他值)
  • 2)group…by 子句是可选的,用来指定选择的项如何被分组。

示例:

       static void Main(string[] args)
        {
            var students = new[]
            {
              new { LName = "Jones", FName = "Mary" , Age = 19, Major = "History" },
              new { LName = "Smith", FName = "Bob" , Age = 20, Major = "CompSci" },
              new { LName = "Fleming", FName = "Carol" , Age = 21, Major = "History" },
          };

            var query = from s in students
                        select s;

            foreach (var q in query)
                Console.WriteLine($"{ q.LName },{ q.FName },{ q.Age },{ q.Major }");

            Console.ReadKey();
        }

输出结果:

Jones,Mary,19,History
Smith,Bob,20,CompSci
Fleming,Carol,21,History

也可以使用 select 子句来选择对象的某些字段。

var query = from s in students
			select s.LName;

foreach(var q in query)
Console.WriteLine(q);

输出结果:

Jones
Smith
Fleming

四、查询中的匿名类型

查询结果可以由原始集合的项、原始集合中项的字段或匿名类型组成。

select new { s.LastNmae, s.FirstName, s.Major };

示例:

       static void Main(string[] args)
        {
            var students = new[]
            {
              new { LName = "Jones", FName = "Mary" , Age = 19, Major = "History" },
              new { LName = "Smith", FName = "Bob" , Age = 20, Major = "CompSci" },
              new { LName = "Fleming", FName = "Carol" , Age = 21, Major = "History" },
          };

            var query = from s in students
                        select new { s.LName, s.FName, s.Major };

            foreach (var q in query)
                Console.WriteLine($"{ q.LName },{ q.FName } -- { q.Major }");

            Console.ReadKey();
        }

//创建匿名类型:s.LName, s.FName, s.Major
//匿名类型的访问字段:q.LName、q.FName、q.Major

输出结果:

Jones,Mary – History
Smith,Bob – CompSci
Fleming,Carol – History

五、group 子句

group 子句根据指定的标准对选择的对象进行分组。

有关 group 子句的要点:

  • 如果项包含在查询的结果中,它们就可以根据某个字段的值进行分组。作为分组依据的属性叫键(key)。

  • group 子句返回的不是原始数据源中项的枚举,而是返回可以枚举已经形成的项的分组的可枚举类型。

  • 分组本身是可枚举类型,它们可以枚举实际的项。

group student by student.Majot;

示例:

      static void Main(string[] args)
        {
            var students = new[]
            {
              new { LName = "Jones", FName = "Mary" , Age = 19, Major = "History" },
              new { LName = "Smith", FName = "Bob" , Age = 20, Major = "CompSci" },
              new { LName = "Fleming", FName = "Carol" , Age = 21, Major = "History" },
          };

            var query = from student in students
                        group student by student.Major;

            foreach (var g in query)//枚举分组
            {
                Console.WriteLine("{0}", g.Key);

                foreach (var s in g)//枚举分组中的项
                    Console.WriteLine($"   { s.LName },{ s.FName }");
            }

            Console.ReadKey();
        }

//分组键:g.Key

输出结果:

History
Jones,Mary
Fleming,Carol
CompSci
Smith,Bob

图20-10演示了从查询表达式返回并保存于查询变量中的对象。

  • 从查询表达式返回的对象是从查询中枚举分组结果的可枚举类型。
  • 每一个分组由一个叫作键的字段区分。
  • 每一个分组本身是可枚举类型并且可以枚举它的项。

请添加图片描述

六、查询延续:into 子句

查询延续子句可以接受查询的一部分的结果并赋予一个名字,从而可以在查询的另一部分中使用。

示例:

        static void Main(string[] args)
        {
            var groupA = new[] { 3, 4, 5, 6 };
            var groupB = new[] { 4, 5, 6, 7 };

            var someInts = from a in groupA
                           join b in groupB on a equals b
                           into groupAandB //查询延续
                           from c in groupAandB
                           select c;

            foreach (var v in someInts)
                Console.Write($"{ v } ");

            Console.ReadKey();
        }

输出结果:

4 5 6

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

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

相关文章

Nginx服务器的六个修改小实验

一、Nginx虚拟主机配置 1.基于域名 &#xff08;1&#xff09;为虚拟主机提供域名解析 配置DNS 修改/etc/hosts文件 &#xff08;2&#xff09;为虚拟主机准备网页文档 #创建网页目录 mkdir -p /var/www/html/abc mkdir -p /var/www/html/def ​ #编写简易首页html文件 ec…

Finalshell安全吗?Xshell怎么样?

文章目录 一、我的常用ssh连接工具二、Xshell2.1 下载&#xff1a;认准官网2.2 Xshell 配置2.3 Xftp和WinSCP 一、我的常用ssh连接工具 之前讲过&#xff1a; 【服务器】远程连接选SSH&#xff08;PUTTY、Finalshell、WinSCP&#xff09; 还是 远程桌面&#xff08;RDP、VNC、…

代码随想录训练营第四十二天|01背包、416.分割等和子集

01背包 代码随想录理论讲解 背包问题分类 01背包 问题描述 有n件物品和一个最多能背重量为w的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i]。每件物品只能用一次&#xff0c;求解将哪些物品装入背包里物品价值总和最大。 动归五部曲 确定dp数组及下…

基于java web高校社交系统 /springboot高校社交系统

摘 要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的系统应运而生&#xff0c;各行各业相继进入信息管理时代&#…

CSS处理页面元素浮动的几个办法

CSS处理页面元素浮动的几个办法 不使用浮动的情况下&#xff0c;子盒子1和2分别在盒子1中占据一行的空间。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" cont…

Java 8新特性:方法引用的介绍与使用

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 1. 什么是方法引用&#xff1f; 2. 方法引用的…

【30天熟悉Go语言】9 Go函数全方位解析

作者&#xff1a;秃秃爱健身&#xff0c;多平台博客专家&#xff0c;某大厂后端开发&#xff0c;个人IP起于源码分析文章 &#x1f60b;。 源码系列专栏&#xff1a;Spring MVC源码系列、Spring Boot源码系列、SpringCloud源码系列&#xff08;含&#xff1a;Ribbon、Feign&…

【好书精读】网络是怎样连接的 之 数据收发完成之后 从服务器断开并删除套接字

&#xff08; 该图由AI制作 &#xff09; 目录 数据收发完成后协议栈要执行的操作 数据发送完毕后断开连接 删除套接字 数据收发操作小结 第一步是创建套接字 然后 客户端会向服务器发起连接操作 数据收发阶段 执行断开操作 数据收发完成后协议栈要执行的操作 数据发…

html_css模拟端午赛龙舟运动

文章目录 ⭐前言&#x1f496; 样式布局&#x1f496; 添加龙舟&#x1f496; 添加css_animation运动 ⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本期给大家分享css实现赛龙舟运动。 &#x1f496; 样式布局 风格&#xff1a;卡通 首先采用一张包括水元素的照片…

液体泄露识别检测算法 监控识别管道液体泄漏

液体泄露识别检测算法通过 yolov8python网络模型技术&#xff0c;液体泄露识别检测算法对管道的液体泄露情况进行全天候不间断实时监测&#xff0c;检测到画面中管道设备液体泄露现象时&#xff0c;将自动发出警报提示相关人员及时采取措施。YOLOv8 算法的核心特性和改动可以归…

硬件入门之什么是二级管

硬件入门之什么是二级管 文章目录 硬件入门之什么是二级管一、二极管是什么&#xff1f;二极管在电路中的作用很广泛&#xff1a; 单向导电&#xff0c;续流&#xff0c;稳压等等 二、分类二极管实际应用场景二极管分类1.通用二极管2..肖特二极管 3.稳压二极管&#xff08;利用…

零基础学会python编程——输入 / 输出函数与变量

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​ 目录 前言 学习目标 一.输入与输出函数 1.print 函数 【例2-1】 【例2-2】 【例2-3】 …

深度详解Nginx正向代理与反向代理

正向代理和反向代理的概念 1、正向代理2、反面代理以租房为例解释正向代理和反向代理&#xff1f;正向代理和反向代理配置 1、正向代理 它的工作原理就像一个跳板,简单的说,我是一个用户,我访问不了某网站,但是我能访问一个代理服务器&#xff0c;这个代理服务器呢,他能访问那个…

一文弄懂git原理及相关操作

文章目录 前言Git 是什么&#xff1f;Git 与 SVN 的区别Git 快速入门Git 相关网站Git 工作流程Git 工作空间Git 文件状态 Git 安装在 Linux 上安装在 Mac 上安装在 Windows 上安装从源代码安装 Git 配置Git 常用命令git initgit clonegit addgit commitgit branchgit tag查看信…

字符设备驱动内部实现原理解析

字符设备驱动内部实现原理解析 一. 字符设备驱动对象内部实现原理解析二. 字符设备驱动的注册流程三. 代码示例 一. 字符设备驱动对象内部实现原理解析 用户层&#xff1a; ​ 当用户打开&#xff08;open&#xff09;一个文件时,会生成一个文件描述符表 内核层&#xff1a; 内…

极致呈现系列之:Echarts散点图的数据魔力

目录 什么是散点图散点图的特点及应用场景散点图的特点散点图的应用场景 Echarts中散点图的常用属性Vue3中创建散点图美化散点图样式 在数据分析和可视化过程中&#xff0c;散点图是一种常见且重要的工具。散点图可以帮助我们直观地观察两个变量之间的关系&#xff0c;并发现其…

MySQL实战解析底层---“order by“是怎么工作的

目录 前言 全字段排序 rowid排序 全字段排序 VS rowid排序 前言 在开发应用的时候&#xff0c;一定会经常碰到需要根据指定的字段排序来显示结果的需求以举例市民表为例&#xff0c;假设你要查询城市是“杭州”的所有人名字&#xff0c;并且按照姓名排序返回前1000个人的姓…

20230622作业:字符设备驱动内部实现原理及流程

1.1字符设备驱动内部实现原理 1>用户打开设备open("~/dev/mycdev",O_RDWR);("路径"&#xff0c;打开方式)2>在内核的虚拟文件系统层会同步执行sys_open函数,实现如下操作3>根据open函数的路径&#xff0c;找到struct inode结构体4>在struct…

深入理解深度学习——GPT(Generative Pre-Trained Transformer):GPT-3与Few-shot Learning

分类目录&#xff1a;《深入理解深度学习》总目录 相关文章&#xff1a; GPT&#xff08;Generative Pre-Trained Transformer&#xff09;&#xff1a;基础知识 GPT&#xff08;Generative Pre-Trained Transformer&#xff09;&#xff1a;在不同任务中使用GPT GPT&#x…

单点登录设计方案介绍及用OAuth完整实现一个单点登录系统

文章目录 一、单点登录系统的意义1.1 提高用户体验1.2 提高安全性1.3 降低开发成本1.4 提高操作效率 二、单点登录的实现方式2.1 基于共享cookie的方式2.2 基于代理服务器的方式2.3 基于SAML协议的方式2.4 基于OAuth协议的方式 三、用OAuth实现单点登录3.1 OAuth 2.0 协议简介3…