C#入门系列 -- LINQ的查询语法

举报
陈言必行 发表于 2022/03/19 13:58:31 2022/03/19
【摘要】 1. LINQ的两种语法写LINQ时有两种形式的语法:(1)查询语法(query syntax)查询语法是声明形式的,使用查询表达式形式来书写。(2)方法语法(method syntax)方法语法是命令形式的,它使用的是标准的方法调用。方法是一组叫做标准查询运算符的方法。微软推荐使用查询语法,因为它更易读,能更清晰的表明查询意图,因此也不容易出错。然而,有一些运算符必须使用方法语法来书写。...

1. LINQ的两种语法

写LINQ时有两种形式的语法:
(1)查询语法(query syntax)查询语法是声明形式的,使用查询表达式形式来书写。
(2)方法语法(method syntax)方法语法是命令形式的,它使用的是标准的方法调用。方法是一组叫做标准查询运算符的方法。

微软推荐使用查询语法,因为它更易读,能更清晰的表明查询意图,因此也不容易出错。然而,有一些运算符必须使用方法语法来书写。

所以我们通常在一个查询中可以使用两种方法的组合。查询表达式使用的查询语法会被C#编译器转换为方法调用的形式、这两种形式在运行时性能上没有区别


2. 查询变量

LINQ查询可以返回两种类型的结果:
(1)可枚举的一组数据,它列出了满足查询参数的项列表;
(2)标量,它是满足查询条件的结果的某种摘要形式。

		static void Main(string[] args)
        {          
            int[] numberArr = new int[] { 100, 90, 80, 70, 60, 50, 40, 30, 20, 10 };
            Stopwatch sw1 = new Stopwatch();
            sw1.Start();
            //在numberArr表中查找大于等于60的元素
            IEnumerable<int> numRes = from num in numberArr where num >= 60 select num;
            foreach (int i in numRes)
            {
                Console.WriteLine(i);
            }
            sw1.Stop();
            Console.WriteLine("numCount:" + sw1.Elapsed);

            Stopwatch sw = new Stopwatch();
            sw.Start();
            int numCount = (from num in numberArr where num >= 60 select num).Count();
            Console.WriteLine(numCount);
            sw.Stop();

            Console.WriteLine("numCount:" + sw.Elapsed);

            Console.ReadKey();
        }

111

LINQ查询返回两种类型结果的差别还在于查询执行的时间:
(1)如果查询表达式返回可枚举的一组数据,查询一直到处理枚举时才会被执行。如果枚举被处理多次,则查询会被执行多次;如果在进行便利之后,查询执行之前数据有改动,则查询会使用新的数据。
(2)如果查询表达式返回标量,查询立刻执行,并且把结果保存在查询变量中。

3. 查询表达式的结构

1)from子句

from子句指定了要作为数据源使用的数据集合。语法格式如下所示:

==from 数据类型 迭代变量 in 要查询的数据源==

对from子句的说明如下:
① 迭代变量有序表示数据源的每一个元素;
② 数据类型是集合中元素的类型,数据类型是可选的,因为编译器会从集合来自动推断出迭代变量的类型;
③ 要查询的集合必须是可以枚举的。

2)where子句

where子句根据之后的运算来去除不符合指定条件的项。如下所示是where子句的语法:

==where 布尔表达式==

where子句将布尔表达式,即谓词,应用于由迭代变量引用的每个源元素,并返回满足指定条件的元素。

使用where子句需注意以下几点:
(1)where子句是一种筛选机制,它不能是查询表达式中的第一个或最后一个子句;
(2)如果where子句中设定的布尔表达式对当前数据源的元素无效,则会发生编译错误;
(3)编译时,where关键字会被转换为where标准查询运算符方法的调用。

3)select子句

select子句指定所选择的对象那部分应该被选择。它可以指定下面的任意一项:
(1)整个数据项
(2)数据项的一个字段
(3)数据项中的几个字段组成的新对象(或类似其他值)

select子句的结果基于前面所有子句的计算结果以及select子
句本身的所有表达式。

==查询表达式必须以 select子句或group子句结束。==


4)group子句

group子句是可选的,用来指定选定的项如何被分组。使用
group子句的注意事项如下:
(1)如果项包括在查询的结果中,就可以根据某个字段的值进行分组。作为分组依据的项叫做键;
(2)group子句不从原始的数据源中返回可枚举项的枚举类型,而是返回已经形成的可以枚举项的分组的可枚举类型;
(3)分组本身是可枚举类型,它们可以枚举实际的项。

使用示例:

 var Persons = new[] { new { Name = "Czhenya", Sex = "男" }, new { Name = "CZY", Sex = "boy" }, new { Name = "CXY_CZY", Sex = "1" } };
 var psoGruop = from pos in Persons group pos by pos.Name;
 foreach (var item in psoGruop)
 {
    Console.WriteLine(item.Key);
    foreach (var i in item)
    {
        Console.WriteLine(i.Name + "..." + i.Sex);
     }               
 }

示例


5)orderby子句

orderby子句接受一个表达式并根据表达式依次返回结果项orderby子句的语法如下所示:
==orderby 表达式 [ ascending |descending]]==

不写后缀默认是升序排序方式,
可以有任意多个orderby子句,但是必须使用逗号分割。

var Persons = new[] { new { Name = "Czhenya", Sex = "男", Age = 1 }, new { Name = "CZY", Sex = "boy", Age = 3 }, new { Name = "CXY_CZY", Sex = "1", Age = 2 } };

var shengXu = from pos in Persons orderby pos.Age ascending select pos;
foreach (var i in shengXu)
{
    Console.WriteLine(i.Name + "..." + i.Age);
}

var jiangXu = from pos in Persons orderby pos.Age descending select pos;
foreach (var i in jiangXu)
{
   Console.WriteLine(i.Name + "..." + i.Age);
}

222
上面这个例子使用Age这个字段,也可以使用Name这个字段会根据英文字母排序,若Name有中文也是可以排序的,可以自行尝试下.


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。