当前位置: 首页 > news >正文

第20章 LINQ 笔记

第20章 LINQ

20.1 什么是LINQ

LINQ代表语言集成查询(Language Integrated Query)

LINQ是.NET框架的扩展,允许使用SQL查询数据库的方式类查询数据集合

static void Main()
{int[] numbers = { 2, 12, 5, 15 }; // Data sourceIEnumerable<int> lowNums = // Define and store the query.from n in numberswhere n < 10select n;foreach (var x in lowNums) // Execute the query.Console. Write($"{ x }, ");
}// output
2, 5,

20.2 LINQ提供程序

对于每一种数据源类型,有对应的LINQ查询的代码模块,叫做LINQ提供程序。

LINQ的体系结构,支持LINQ的语言以及LINQ提供程序
在这里插入图片描述

匿名类型

匿名类型常用于LINQ查询的结果中

创建匿名类型的变量,使用new关键字、对象初始化语句

new { FieldProp = InitExpr, FieldProp = InitExpr, ...}

具体示例

static void Main( )
{var student = new {Name="Mary Jones", Age=19, Major="History"};// Must use var Anonymous object initializerConsole.WriteLine($"{ student.Name }, Age { student.Age }, Major: { student.Major}");
}// output
Mary Jones, Age 19, Major: History

主要事项:

匿名类型只能用于局部变量,不能用于类成员

匿名类型使用var关键字作为变量类型

匿名类型创建的属性是只读的

对象初始化语句

// 赋值形式、成员访问表达式、标识符形式
var student = new { Age = 19, Other.Name, Major };

示例

class Other
{static public string Name = "Mary Jones";
}
class Program
{static void Main(){string Major = "History";Assignment form Identifiervar student = new { Age = 19, Other.Name, Major};Member accessConsole.WriteLine($"{student.Name }, Age {student.Age }, Major: {student.Major}");}
}// output
Mary Jones, Age 19, Major: History

如果编译器遇到另一个具有相同参数名、推断类型、顺序的匿名类型对象初始化语句,会重用这个类型直接创建新的实例,不会创建新的匿名类型。

20.3 方法语法和查询语法

方法语法 使用标准的方法调用,命令式的,指明了查询方法调用的顺序

查询语法 使用查询表达式书写,是声明式的查询想要返回的东西

微软推荐使用查询语法,更易读、更清晰地标名查询意图,更不容易出错

static void Main( )
{int[] numbers = { 2, 5, 28, 31, 17, 16, 42 };var numsQuery = from n in numbers // Query syntaxwhere n < 20select n;var numsMethod = numbers.Where(N => N < 20); // Method syntaxint numsCount = (from n in numbers // Combinedwhere n < 20select n).Count();foreach (var x in numsQuery)Console.Write($"{ x }, ");Console.WriteLine();foreach (var x in numsMethod)Console.Write($"{ x }, ");Console.WriteLine();Console.WriteLine(numsCount);
}// output
2, 5, 17, 16,
2, 5, 17, 16,
4

20.4 查询变量

查询可以返回两种类型的结果:

枚举数据 是满足查询参数的项列表

标量 是满足查询条件的结果的某种摘要形式

int[] numbers = { 2, 5, 28 };
// 枚举器
IEnumerable<int> lowNums = from n in numbers // Returns an enumeratorwhere n < 20select n;// 返回项的总和
int numsCount = (from n in numbers // Returns an intwhere n < 20select n).Count();

20.5 查询表达式的结构

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

子句必须按照一定顺序出现

from子句和select group子句两部分是必需的

其他子句可选的

select子句在表达式最后

可以有任意多的from let where 子句
在这里插入图片描述

20.5.1 from子句

from子句指定了要作为数据源使用的数据集合

迭代遍历逐个表示数据源的每一个元素

from子句语法

Type 是集合中元素的类型,可选的,编译器可以从结合中推断类型

Item 迭代遍历的名字

Items 查询集合的名字

from Type Item in Items
int[] arr1 = {10, 11, 12, 13};
// Iteration variable
var query = from item in arr1where item < 13 // Uses the iteration variableselect item; // Uses the iteration variable
foreach( var item in query )Console.Write( $ "{ item },");// output
10, 11, 12

20.5.2 join子句

使用联结来结合两个或更多集合中的数据

联结操作接受两个集合,创建一个临时的对象集合,其中每个对象包含两个原始集合对象中所有的字段

联结语法

// 使用equals 关键字
join Identifier in Collection2 on Field1 equals Field2

示例

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

20.5.3 什么是联结

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

class Program
{public class Student { // Declare classes.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" },};// Initialize arrays.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( ){// Find the last names of the students taking history.var query = from s in studentsjoin c in studentsInCourses on s.StID equals c.StIDwhere c.CourseName == "History"select s.LastName;// Display the names of the students taking history.foreach (var q in query)Console.WriteLine($"Student taking History: { q }");}
}//output
Student taking History: Carson
Student taking History: Fleming

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

from…let…where是查询主体的第一部分,可选的,由任意数量的3种子句构成:from子句、let子句、where子句
在这里插入图片描述

1.from子句

查询表达式必需从from子句开始,后面是查询主体

static void Main()
{var groupA = new[] { 3, 4, 5, 6 };var groupB = new[] { 6, 7, 8, 9 };var someInts = from a in groupA // Required first from clausefrom b in groupB // First clause of query bodywhere a > 4 && b <= 8select new {a, b, sum = a + b}; // Object of anonymous typeforeach (var x in someInts)Console.WriteLine(x);
}// output
{ 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子句

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

static void Main()
{var groupA = new[] { 3, 4, 5, 6 };var groupB = new[] { 6, 7, 8, 9 };var someInts = from a in groupAfrom b in groupBlet sum = a + b // Store result in new variable.where sum == 12select new {a, b, sum};foreach (var a in someInts)Console.WriteLine(a);
}// output
{ 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子句根据运算表达式,来去除不符合指定条件的项

static void Main()
{var groupA = new[] { 3, 4, 5, 6 };var groupB = new[] { 6, 7, 8, 9 };var someInts = from int a in groupAfrom int b in groupBlet sum = a + bwhere sum >= 11 // Condition 1where a == 4 // Condition 2select new {a, b, sum};foreach (var a in someInts)Console.WriteLine(a);
}// output
{ a = 4, b = 7, sum = 11 }
{ a = 4, b = 8, sum = 12 }
{ a = 4, b = 9, sum = 13 }

20.5.5 orderby子句

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

排序方向:ascending 升序(默认)、descending 降序

可以有任意多个子句,必须使用逗号分隔

static void Main( ) {var students = new [] // Array of objects of an anonymous type{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 studentsorderby student.Age // Order by Age.select student;foreach (var s in query) {Console.WriteLine($"{ s.LName }, { s.FName }: { s.Age }, { s.Major }");}
}// output
Jones, Mary: 19, History
Smith, Bob: 20, CompSci
Fleming, Carol: 21, History

20.5.6 select…group子句

由两种类型的子句组成:select子句、group…by子句

select子句指定要选择所选对象的哪些部分,可以是以下任意一项:

整个数据项

数据项的一个字段

数据项中几个字段组成的新对象

group…by子句 可选的,用来指定选择的项如何被分组。

select Expression
group Expression1 by Expression2

示例 - 使用select子句选择整个数据项

using System;
using System.Linq;
class Program {static void Main() {var students = new[] // Array of objects of an anonymous type{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 studentsselect s;foreach (var q in query)Console.WriteLine($"{ q.LName }, { q.FName }: { q.Age }, { q.Major }");}
}// output
Jones, Mary: 19, History
Smith, Bob: 20, CompSci
Fleming, Carol: 21, History

示例 - 使用select子句选择对象的某些字段

var query = from s in studentsselect s.LName;
foreach (var q in query)Console.WriteLine(q);// output
Jones
Smith
Fleming

20.5.7 查询中的匿名类型

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

select子句 用大括号包围的字段,使用逗号分隔 来创建匿名类型

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

示例

using System;
using System.Linq;
class Program
{static void Main(){var students = new[] // Array of objects of an anonymous type{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 studentsselect new { s.LName, s.FName, s.Major };foreach (var q in query)Console.WriteLine($"{ q.FName } { q.LName } -- { q.Major}");} 
}//output
Mary Jones -- History
Bob Smith -- CompSci
Carol Fleming -- History

20.5.8 group子句

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

作为分组依据的属性叫做键

返回 已经形成项的分组的可枚举类型

语法示例

group student by student.Major;

示例-根据学生主修课程进行分组

static void Main( )
{var students = new[] // Array of objects of an anonymous type{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 studentsgroup student by student.Major;foreach (var g in query) // Enumerate the groups.{Console.WriteLine("{0}", g.Key);foreach (var s in g) // Enumerate the items in the group.Console.WriteLine($" { s.LName }, { s.FName }");}
}// output
HistoryJones, MaryFleming, Carol
CompSciSmith, Bob

20.5.9 查询延续:into子句

查询延续子句可以接受查询的一部分的结果并赋予一个名字,可以在查询的另一个部分中使用
在这里插入图片描述

示例 查询联结了groupA和groupB,并将结果命名未groupAandB

static void Main()
{var groupA = new[] { 3, 4, 5, 6 };var groupB = new[] { 4, 5, 6, 7 };var someInts = from a in groupAjoin b in groupB on a equals binto groupAandB // Query continuation from c in groupAandBselect c;foreach (var v in someInts)Console.Write($"{ v } ");
}

20.6 标准查询运算符

20.6.1 标准查询运算符的签名
20.6.2 查询表达式和标准查询运算符
20.6.3 将委托作为参数
20.6.4 LINQ预定义的委托类型
20.6.5 使用委托参数的示例
20.6.6 使用Lambda表达式参数的示例

20.7 LINQ to XML

20.7.1 标记语言
20.7.2 XML基础
20.7.3 XML类
20.7.4 使用XML特性
20.7.5 其他类型的节点
20.7.6 使用LINQ toXML的LINQ查询

http://www.dtcms.com/a/332909.html

相关文章:

  • Akka的容错机制,监督策略与熔断器的区别
  • 【时时三省】(C语言基础)共用体类型
  • 深度解析 DDoS 攻击:运作机制与防御体系构建​
  • 金融项目高可用分布式TCC-Transaction(开源框架)
  • 01数据结构-拓扑排序
  • Go语言实战案例:静态资源服务(CSS、JS、图片)
  • 迁移学习的常见研究领域(附有相关资料)
  • Kubernetes(2)pod的管理及优化
  • 数据结构初阶(17)排序算法——非比较排序、排序算法总结
  • LintCode第107题-单词拆分-新版
  • 国产操作系统之openEuler:根深叶茂
  • 力扣习题:基本计算器
  • 通过CANopen 配置闭环驱动器C5-E——易格斯igus
  • platform总线注册流程分析
  • CUDA 编程笔记:使用 CUDA 加速数组总和
  • 102、【OS】【Nuttx】【周边】文档构建渲染:安装 Esbonio 服务器
  • 【JavaEE】多线程 -- 死锁问题
  • linux服务器查看某个服务启动,运行的时间
  • 如何将 iPhone 应用程序传输到新 iPhone?
  • C++ rapidjson库使用示例
  • 【慕伏白】CTFHub 技能树学习笔记 -- Web 前置技能之HTTP协议
  • Vue 侦听器(watch 与 watchEffect)全解析3
  • 【ESP32】ESP32-P4 通过 SDIO 连接 ESP32-C6
  • FCC认证三星XR头显加速全球量产,微美全息AI+AR技术引领智能眼镜硬件创新
  • webgis-maps通用地图框架库(leaflet+mapbox)
  • 《探秘浏览器Web Bluetooth API设备发现流程》
  • K8S-Pod资源对象
  • 英语角的恢复重建!
  • 【入门级-算法-6、排序算法:排序的基本概念冒泡排序】
  • uniapp小程序ocr-navigator身份证拍照上传替换方案