当前位置:网站首页>C# 一周入门高级编程之《C#-LINQ》Day Four
C# 一周入门高级编程之《C#-LINQ》Day Four
2022-08-11 03:46:00 【太阳风暴】
C# 一周入门高级编程之《C#-LINQ》
一、C# LINQ 是什么
C# 的LINQ语法类似数据库的查询方法,是一种数据集合的查询语法,LINQ可以直接查询数据库、泛型、以容器、以及xml文档。什么意思呐?我们对于一个集合可能操作就是通过循环,给出判断条件,然后满足条件的话就把这个元素添加到一个新的集合内返回就行啦,但是C#提供了另外的方法,就是用LINQ查询语法,用类似SQL语法对可查询对象进行筛选,就这个开发效率就很高了,而且这样的写法还很方便。
- 这篇文章主要是讲述 基本的 LINQ 对于泛型、容器的一些操作,
- 数据库部分、xml文档部分我暂时没有研究。分组以及连接部分暂未深入掌握
二、LINQ基础用法
初次尝试使用LINQ语法,下面有对几种集合类型进行查询例子,语法非常容易懂,可以工具可以好好利用。
使用LINQ有三个步骤。
- 指定数据源
- 创建查询语句
- 执行查询
如下面 代码例子所示
1. 对数组查询
如下对数组进行查询 大于100的元素
//创建数据源
int[] intList = {
32, 35, 43, 654, 76, 56, 57, 453, 3542, 46 };
//创建查询语句
IEnumerable<int> searchRes = from item in intList
where item >100
select item;
//执行查询
foreach(var item in searchRes)
{
Console.WriteLine(item);
}
//结果如下
654
453
3542
2. 对容器查询
如下对字符串列表查询
//创建数据源
List<string> stringList = new List<string>() {
"Helan","Linken", "Black", "Brownd", "Kindey" };
//创建查询语句
IEnumerable<string> stringSearchList = from item in stringList
where item.StartsWith("B") || item.StartsWith("K")
select item;
//执行查询
foreach(var item in stringSearchList)
{
Console.WriteLine(item);
}
//结果如下
Black
Brownd
Kindey
3. 对IEnumerable<>查询
//创建数据源
IEnumerable<double> doubeList = new double[]{
32.4, 3.25, 35.4, 3.65, 4.74, 3.575, 4.6675 };
//创建查询语句
var doubleSearchList = from item in doubeList
where item > 20.11
select item;
//执行查询
foreach(var item in doubleSearchList)
{
Console.WriteLine(item);
}
//结果如下
32.4
35.4
4. 非泛型(IEnumerable)如 ArrayList
对 这种非泛型查询需要指定 数据 对象的类型, 不然推断不出来是什么类型 ,因为其实泛型已经指明了数据项的类型
//创建数据源
ArrayList arrayList = new ArrayList() {
42, 34, 43, 434, -4, 354, 65, 754, 7, -43, 764, 2, };
//创建查询语句
var arrayListRes = from int item in arrayList
where item <= 0
select item;
//执行查询
foreach(var item in arrayListRes)
{
Console.WriteLine(item);
}
//查询结果
-4
-43
三、获取数据源
所谓获取数据源,其实在上面例子中已经说明很清晰啦,数据源其实就是一个数据集合,我们需要指定一个集合作为我们查询的基础条件,在 LINQ 查询中,第一步是指定数据源。 在 LINQ 查询中,先使用 from 子句引入数据源以及数据项。
- 如下:
//创建数据源
IEnumerable<double> doubeList = new double[]{
32.4, 3.25, 35.4, 3.65, 4.74, 3.575, 4.6675 };
//from 则是引入数据源 以及指定数据项
var doubleSearchList = from item in doubeList
....
- 查询表达式中不会真正发生迭代
- 当执行查询时,才会迭代 也即是 使用了 foreach 查询关键词时
四、选择对象
选择对象其实就是 select item,select 子句生成查询结果并指定每个返回的元素的“形状”或类型。 例如,可以指定结果包含的是整个 Customer 对象、仅一个成员、成员的子集,还是某个基于计算或新对象创建的完全不同的结果类型。 这就牛逼了,意思就是说 满足条件的 数据项 可以对其进行一定的操作再返回
- 当 select 子句生成除源元素副本以外的内容时,该操作称为投影。(只要不是 from item in xxx select item) 结果只要不是原来的副本就是投影
示例:选择以 B ,K 开头的字符串并全部转为大写
List<string> stringList = new List<string>() {
"Helan","Linken", "Black", "Brownd", "Kindey" };
IEnumerable<string> stringSearchList = from item in stringList
where item.StartsWith("B") || item.StartsWith("K")
select item.ToUpper();
foreach(var item in stringSearchList)
{
Console.WriteLine(item);
}
//结果
BLACK
BROWND
KINDEY
五、筛选
筛选其实就是使用一定的条件过滤出我们想要的结果,使用的关键字就是 where ,在上面的很多例子里都使用了where 作为筛选条件。
- 筛选器查询 仅返回表达式为 true 的元素。
- 筛选器实际指定要从源序列排除哪些元素。
那就知道了 where 后面跟一个能计算出为 bool true 的表达式即可
能返回 true 的表达式就相对灵活了 可以是
- 逻辑运算符: !|| && > < == !=
- 函数式
var queryLondonCustomers = from cust in customers
where cust.City == "London"
select cust;
where cust.City == "London" && cust.Name == "Devon"
where cust.City == "London" || cust.City == "Paris"
一个查询表达式可以包含多个 where 子句,一个子句可以包含多个where子表达式。(不推荐这么用)
如下,结果都一样,第二个比较费脑子些
// 数据源
int[] numbers = {
5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
// 查询表达式
var queryLowNums2 =
from num in numbers
where num < 5 && num % 2 == 0
select num;
// 执行筛选
foreach (var s in queryLowNums2)
{
Console.Write(s.ToString() + " ");
}
Console.WriteLine();
// 查询表达式
var queryLowNums3 =
from num in numbers
where num < 5
where num % 2 == 0
select num;
// 执行筛选
foreach (var s in queryLowNums3)
{
Console.Write(s.ToString() + " ");
}
//结果
// 4 2 0
// 4 2 0
- where 子句是一种筛选机制。 除了不能是第一个或最后一个位置外,它几乎可以放在查询表达式中的任何位置。 where 子句可以出现在 group 子句的前面或后面,具体取决于时必须在对源元素进行分组之前还是之后来筛选源元素。
六、排序
在查询表达式中,orderby 子句可对满足条件的序列或子序列(组)以升序或降序排序。 同时我们可以使用一个个或多个次级排序操作,可以指定多个键来排序。 元素类型的默认比较器执行排序。 默认排序顺序为升序。 还可以指定自定义比较器。
排序的方式有两种:一种升序,一种降序
- 升序:从小到大
- 降序:从大到小
- 数值类:按照 大小排列
- 字符串:按照 首字母 A-Z 或者 Z-A排列
最简单的使用用法之一如下:
// 待查询类的属性
public class Customer
{
public string Name{
get;set;}
public string City{
get;set;}
}
//数据源
List <Customer> customers = new List <Customer>(){
/*一系列初始化*/};
//查询London 城市的Name, 按照升序排列A-Z排序
//若 对结果进行从 Z 到 A 的逆序排序,使用 orderby descending即可
var queryLondonCustomers3 =
from cust in customers
where cust.City == "London"
orderby cust.Name ascending
select cust;
简单排序查询-示例
// 创建数据源
string[] fruits = {
"cherry", "apple", "blueberry" };
// 查询语句-升序
IEnumerable<string> sortAscendingQuery =
from fruit in fruits
orderby fruit //默认升序
select fruit;
// 查询语句-降序
IEnumerable<string> sortDescendingQuery =
from w in fruits
orderby w descending
select w;
// 执行查询
Console.WriteLine("Ascending:");
foreach (string s in sortAscendingQuery)
{
Console.WriteLine(s);
}
// 执行查询
Console.WriteLine(Environment.NewLine + "Descending:");
foreach (string s in sortDescendingQuery)
{
Console.WriteLine(s);
}
//结果
Ascending:
apple
blueberry
cherry
Descending:
cherry
blueberry
apple
除了可以直接排序一次,还可以使用次要排序,次要排序的意思其实就是说,在第一轮排序内部的肯定在同级下面有很多相同的数据,我们还可以对其进一步这个已排序组内再进行一次排序。下面看官网的示例就知道啦
// 数据源的数据项的具体描述
public class Student
{
public string First {
get; set; }
public string Last {
get; set; }
public int ID {
get; set; }
}
//产生一个数据集合
public static List<Student> GetStudents()
{
List<Student> students = new List<Student>
{
new Student {
First="Svetlana", Last="Omelchenko", ID=111},
new Student {
First="Claire", Last="O'Donnell", ID=112},
new Student {
First="Sven", Last="Mortensen", ID=113},
new Student {
First="Cesar", Last="Garcia", ID=114},
new Student {
First="Debra", Last="Garcia", ID=115}
};
return students;
}
//主函数执行
static void Main(string[] args)
{
// 产生数据源
List<Student> students = GetStudents();
// 创建查询
IEnumerable<Student> sortedStudents =
from student in students
orderby student.Last ascending, student.First ascending
//先按照 Last 升序排,在升序组内再安装 First 排序即可
select student;
// 执行查询
Console.WriteLine("sortedStudents:");
foreach (Student student in sortedStudents)
{
Console.WriteLine(student.Last + " " + student.First);
}
//这里涉及到分组的知识,分组的基本条件是要排序后再分组,
var sortedGroups =
from student in students
orderby student.Last, student.First //忽略了 ascending 关键词
group student by student.Last[0] into newGroup //分组按照 Last首字母,分组后把分组结果塞到newGroup
orderby newGroup.Key //分组的集合再排序一次
select newGroup;
// 执行查询
Console.WriteLine(Environment.NewLine + "sortedGroups:");
foreach (var studentGroup in sortedGroups)
{
Console.WriteLine(studentGroup.Key);
foreach (var student in studentGroup)
{
Console.WriteLine(" {0}, {1}", student.Last, student.First);
}
}
}
/* Output: sortedStudents: Garcia Cesar Garcia Debra Mortensen Sven O'Donnell Claire Omelchenko Svetlana sortedGroups: G Garcia, Cesar Garcia, Debra M Mortensen, Sven O O'Donnell, Claire Omelchenko, Svetlana */
七、分组
分组和数据的基本一致,要使用分组的特性就需要使用group 关键字, 在分组语句中 毫无疑问需要我们指定分组的方式,这个方式一般通过统一的类型,就是键 key。分组的结果就是一个键值对, 例如,我们可指定按 City 对结果进行分组,使来自 London 或 Paris 的所有客户位于单独的组内。
- 使用 group 子句结束查询时,结果将以列表的形式列出。 列表中的每个元素都是具有 Key 成员的对象,列表中的元素根据该键被分组。 在循环访问生成组序列的查询时,必须使用嵌套 foreach 循环。 外层循环循环访问每个组,内层循环循环访问每个组的成员。
// queryCustomersByCity 是这种类型: IEnumerable<IGrouping<string, Customer>>
var queryCustomersByCity =
from cust in customers
group cust by cust.City;
// customerGroup 类型结构 IGrouping<string, Customer>
foreach (var customerGroup in queryCustomersByCity)
{
Console.WriteLine(customerGroup.Key);
foreach (Customer customer in customerGroup)
{
Console.WriteLine(" {0}", customer.Name);
}
}
边栏推荐
- js 将字符串作为js执行代码使用
- 【Yugong Series】August 2022 Go Teaching Course 036-Type Assertion
- Power Cabinet Data Monitoring RTU
- 学编程的第十三天
- Kubernetes集群搭建Zabbix监控平台
- 没想到MySQL还会问这些...
- 分布式和集群的区别和联系
- CTO said that the number of rows in a MySQL table should not exceed 2000w, why?
- C语言 recv()函数、recvfrom()函数、recvmsg()函数
- 【FPGA】day21- moving average filter
猜你喜欢
什么是机器强化学习?原理是什么?
【FPGA】名词缩写
Interchangeability Measurements and Techniques - Calculation of Deviations and Tolerances, Drawing of Tolerance Charts, Selection of Fits and Tolerance Classes
【FPGA】day19-二进制转换为十进制(BCD码)
没想到MySQL还会问这些...
【FPGA】day22-SPI protocol loopback
LeetCode刷题第17天之《3 无重复字符的最长子串》
互换性与测量技术——表面粗糙度选取和标注方法
[yu gong series] Go program 035-08 2022 interfaces and inheritance and transformation and empty interface
Description of ESB product development steps under cloud platform
随机推荐
A simple JVM tuning, learn to write it on your resume
什么是三方支付?
2022-08-10 The sixth group Hiding spring study notes
机器学习中什么是集成学习?
二叉树相关代码题【较全】C语言
[FPGA] day19- binary to decimal (BCD code)
Multi-serial port RS485 industrial gateway BL110
AI+医疗:使用神经网络进行医学影像识别分析
What are port 80 and port 443?What's the difference?
UNI-APP_iphone bottom safe area
AI+Medical: Using Neural Networks for Medical Image Recognition and Analysis
【Yugong Series】August 2022 Go Teaching Course 036-Type Assertion
Watch to monitor
Leetcode 450. 删除二叉搜索树中的节点
Homework 8.10 TFTP protocol download function
【C语言】入门
Interchangeability and Measurement Technology—Surface Roughness Selection and Marking Method
En-us is an invalid culture error solution when Docker links sqlserver
QueryDet:级联稀疏query加速高分辨率下的小目标检测
分布式和集群的区别和联系