LINQ之路 5:LINQ查询表达式

书写LINQ查询时又两种语法可供选择:方法语法(Fluent Syntax)和查询表达式(Query Expression)。

LINQ方法语法的本质是通过扩展方法和Lambda表达式来创建查询。C# 3.0对于LINQ表达式还引入了声明式的查询表达式,也叫查询语法,通常来讲,它是创建LINQ查询的更加快捷的方式。尽管通过查询语法写出的查询比较类似于SQL查询,但实际上查询表达式的产生并不是建立在SQL之上,而是建立在函数式编程语言如LISP和Haskell中的list comprehensions(列表解析)功能之上。本篇会对LINQ查询语法进行详细的介绍。

我们在前一篇LINAQ方法语法中所举的示例:获取所有包含字母”a”的姓名,按长度排序并将结果转为大写。下面是与之等价的查询表达式语法:

        static void Main(string[] args)
{
string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" };

IEnumerable<string> query =
from n in names
where n.Contains("a") // Filter elements
orderby n n.Length // Sort elements, (orderby n 改为 orderby n.Length, 感谢网友搏击的小船发现该处错误)
select n.ToUpper(); // Translate each element

foreach (string name in query)
Console.WriteLine(name);
}

查询表达式总是以from子句开始,以select或者group子句结束。From子句定义了查询的范围变量(range variable),可以认为该变量是对输入sequence的一个遍历,就像foreach做的那样。下面这幅图描述了查询表达式的完整语法:

当然,.NET公共语言运行库(CLR)并不具有查询语法的概念。编译器会在程序编译时把查询表达式转换为方法语法,即对扩展方法的调用。这意味着,我们用查询表达式写出来的LINQ查询都有等价的方法语法。对于上例中的查询表达式,编译器会转换成下面的方法语法:

            IEnumerable<string> query = names
.Where (n => n.Contains("a"))
.OrderBy(n => n.Length)
.Select (n => n.ToUpper());

然后,应用编译器对于方法语法的处理规则,上面的Where, OrderBy, Select查询运算符会绑定到Enumerable类中的相应扩展方法。

范围变量

范围变量是紧随from关键字之后定义的变量,一个范围变量指向当前操作符所对应的输入sequence中的当前元素。在我们的示例中,范围变量出现在每一个查询子句中,但要注意的是,变量实际是对不同sequence的遍历,因为Where、OrderBy、Select会有不同的输入sequence:

            IEnumerable<string> query =
from n in names //n是我们定义的范围变量
where n.Contains("a") //n直接来自names array
orderby n.Length //n来自filter之后的subsequent
select n.ToUpper(); //n来自OrderBy之后的subsequent

当 编译器把上面的查询语法翻译成方法语法后,我们会更清楚的看到范围变量的这种行为:

            IEnumerable<string> query2 = names
.Where(n => n.Contains("a")) //n直接来自names array
.OrderBy(n => n.Length) //n来自filter之后的subsequent
.Select(n => n.ToUpper()); //n来自OrderBy之后的subsequent

除了from关键字后面的范围变量,查询表达式还允许我们通过下面的子句引入新的范围变量:

  • let
  • into
  • 额外的from子句

稍后我们会在“LINQ中的子查询、创建策略和数据转换”一篇中讨论他们的使用方法和适用场景。

查询表达式和方法语法

查询表达式和方法语法各有所长。对下面的场景来讲,用查询表达式写出来得查询会更加简洁:

  • 使用let关键字引入新的范围变量
  • 在SelectMany、Join或GroupJoin后引用外部范围变量时

在简单的使用Where、OrderyBy、Select时,两种语法结构并没有大的差别,此时可以根据你的喜好任意选择。

对于只有单个查询运算符组成的查询,方法语法会更加简短和易于理解。

最后,对于没有对应查询表达式关键字的查询运算符,我们就只能选择方法语法了。下面是存在对应查询表达式关键字的运算符:Where、Select、SelectMany、OrderBy、ThenBy、OrderByDescending、ThenByDescending、GroupBy、Join、GroupJoin。

组合查询语法

当一个查询运算符没有对应的查询语法时,我们可以组合使用查询语法和方法语法。唯一的约束是查询中的每一个查询语法部分必须是完整的,如以from开始以select或group结束。如下例:

            string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" };

// 计算包含字母”a”的姓名总数
int matches = (from n in names where n.Contains("a") select n).Count(); // 3
// 按字母顺序排序的第一个名字
string first = (from n in names orderby n select n).First(); // Dick

这种组合语法通常在书写更加复杂的查询时会具有优势,像上面这种简单的查询,我们只需要使用方法语法就能收到很好的效果:

             int matches = names.Where(n => n.Contains("a")).Count();    // 3
string first = (names.OrderBy(n => n)).First(); // Dick

 


系列博客导航:

LINQ之路系列博客导航

LINQ之路 1:LINQ介绍

LINQ之路 2:C# 3.0的语言功能(上)

LINQ之路 3:C# 3.0的语言功能(下)

LINQ之路 4:LINQ方法语法

LINQ之路 5:LINQ查询表达式

LINQ之路 6:延迟执行(Deferred Execution)

LINQ之路 7:子查询、创建策略和数据转换

LINQ之路 8:解释查询(Interpreted Queries)

LINQ之路 9:LINQ to SQL 和 Entity Framework(上)

LINQ之路10:LINQ to SQL 和 Entity Framework(下)

LINQ之路11:LINQ Operators之过滤(Filtering)

LINQ之路12:LINQ Operators之数据转换(Projecting)

LINQ之路13:LINQ Operators之连接(Joining)

LINQ之路14:LINQ Operators之排序和分组(Ordering and Grouping)

LINQ之路15:LINQ Operators之元素运算符、集合方法、量词方法

LINQ之路16:LINQ Operators之集合运算符、Zip操作符、转换方法、生成器方法

LINQ之路17:LINQ to XML之X-DOM介绍

LINQ之路18:LINQ to XML之导航和查询

LINQ之路19:LINQ to XML之X-DOM更新、和Value属性交互

LINQ之路20:LINQ to XML之Documents、Declarations和Namespaces

LINQ之路21:LINQ to XML之生成X-DOM(Projecting)

LINQ之路系列博客后记

 

转载于:https://www.cnblogs.com/lifepoem/archive/2011/10/28/2227735.html

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

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

相关文章

调查谋杀案以换取Obra Dinn

回顾性 (RETROSPECTIVE) I am not sure if this is intentional, but Lucas Pope has a knack for turning the mundane into something special. This was evident in his release of Papers Please. In that game, you’re a border patrolman trying to provide for your fa…

9年前的大一,我们这样为女生过37女生节【祝节日快乐】

这是一篇水文~没啥目的&#xff0c;若说要有&#xff0c;就是希望大家参加源码共读学起来。公众号后台显示所有读者朋友中大约有23%的女生。前端工程师中女生应该占比相对多些。祝关注我公众号的女生3.7女生节快乐&#xff0c;大部分公司明天应该都有半天假期。可以留言大学时你…

Jquery ajax 访问调用带参数的服务方法!

页面脚本中的写法: $.ajax({url: "http://localhost:3510/WebSite/WebService/ExceptionRecoder.asmx/SetExceptionInfo",contentType: "application/json; charsetutf-8", type: "POST", dataType: "js…

requests模块发送带headers的Get请求和带参数的请求

1.在PyCharm开发工具中新建try_params.py文件&#xff1b; 2.try_params.py文件中编写代码&#xff1a; import requests#设置请求Headers头部header {"User-Agent" : "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;"}#请求输入参数p…

面试官问:跨域请求如何携带cookie?

大家好&#xff0c;我是若‍川。持续组织了6个月源码共读活动&#xff0c;感兴趣的可以点此加我微信 ruochuan12 参与&#xff0c;每周大家一起学习200行左右的源码&#xff0c;共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。历史面试系列本文…

Method not found: '!!0[] System.Array.Empty()'.

一开始不知道啥情况&#xff0c;原来是自己把.net 框架改成4.6.1了&#xff0c;客户机是4.0 so.... 把项目改低点&#xff0c;就ok了。转载于:https://www.cnblogs.com/ZaraNet/p/11100207.html

记录点滴8

第8~9周 4月7日~4月22日 第八周的时候实在太多东西要做了&#xff0c;我把写周记这件事给忘了&#xff0c;其实也没太大关系&#xff0c;写跟不写之间也没有太大的鸿沟&#xff0c;只是写了之后&#xff0c;会让我的记忆更加清晰&#xff0c;让自己明白&#xff0c;最近自己做了…

ux设计中的各种地图_移动应用程序设计中的常见UX错误

ux设计中的各种地图Have you ever tried a new app, only to realize you have no idea how to use it?您是否曾经尝试过一个新的应用程序&#xff0c;却发现自己不知道如何使用它&#xff1f; Few things can transport a person from calm and happy, to frustrated and an…

如何使用 Node 后端创建 React 应用程序:完整指南

大家好&#xff0c;我是若川。持续组织了6个月源码共读活动&#xff0c;感兴趣的可以点此加我微信 ruochuan12 参与&#xff0c;每周大家一起学习200行左右的源码&#xff0c;共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。历史面试系列React…

FP error code老是忘记的看这里:只给出最常用的几个。

把常见的几个记牢&#xff0c;不要在比赛时纠结。 错误2&#xff1a;输入文件未找到。 错误106&#xff1a;数据读入的格式错误&#xff0c;往往是读入语句出错。 错误200&#xff1a;被零除。 错误201&#xff1a;范围检查错误&#xff0c;数组越界。 错误202&#xff1a;栈溢…

快速求幂算法

1 #include <stdio.h>2 #include <math.h>3 //递归算法4 int recursion(int a,int b)5 {6 int tem 1;7 if(b0)return 1;8 else if(b1)return a;9 tem recursion(a,b>>1); 10 tem tem*tem; 11 if(b&1) tem tem * a; 12 r…

工业仪器仪表 界面设计_如何设计时尚的仪表板界面

工业仪器仪表 界面设计重点 (Top highlight)Welcome to the second step by step UI guide. Since you really liked my first article on “How to achieve Friendly, Lightweight UI”, I decided to make another one in a similar manner. Please note, that this is not a…

linux ifconfig命令参数及用法详解--linux查看配置网卡命令

ifconfig 是一个用来查看、配置、启用或禁用网络接口的工具&#xff0c;这个工具极为常用的。可以用这个工具来临时性的配置网卡的IP地址、掩码、广播地址、网关等。也可以把 它写入一个文件中&#xff08;比如/etc/rc.d/rc.local)&#xff0c;这样系统引导后&#xff0c;会读取…

给3月要跳槽的前端提个醒!不了解微前端就别去面试了,不然……

在后端架构发展史上&#xff0c;如果要找一个低耦合高内聚架构模式的典范&#xff0c;微服务当仁不让。在互联网业务急速扩张的背景下&#xff0c;微服务架构解决了后端服务中的“重”&#xff0c;让每个服务都能够独立部署、独立扩展&#xff0c;每个服务都具有稳固的模块边界…

调试 SharePoint 解决方案

调试 SharePoint 解决方案 可以使用 Visual Studio 调试器来调试 SharePoint 解决方案。 启动调试后&#xff0c;Visual Studio 会将项目文件部署到 SharePoint Server&#xff0c;然后在Web 浏览器中打开 SharePoint 网站的一个实例。 以下各节说明如何在 Visual Studio 中调试…

ui和ux的区别_UI和UX之间的区别

ui和ux的区别You’ve probably heard a lot of self-proclaimed “UX/UI” designers out there, the word “UI” thrown around endlessly at Apple keynotes, or tech startups saying “we need to fix the UX here and the UX there.”Ÿouve可能听说过很多自称“UX / UI”…

给UIWebView增加搜索栏

在xib文件中拖入UIWebView。使用代码为UIWebView的滚动控件增加搜索栏&#xff1a;UISearchBar* searchBar[[[UISearchBar alloc]initWithFrame:CGRectMake(0, -44, 320, 44)]autorelease];[self.browser.scrollView addSubview:searchBar];self.topBarsearchBar;[[self.browse…

用JS轻松实现一个录音、录像、录屏工具库

大家好&#xff0c;我是若川。持续组织了6个月源码共读活动&#xff0c;感兴趣的可以点此加我微信 ruochuan12 参与&#xff0c;每周大家一起学习200行左右的源码&#xff0c;共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。历史面试系列前言最…

文本字段和表单设计-UI组件系列

重点 (Top highlight)Forms have existed for a significant amount of time, greatly simplifying the task of drafting complaints and various other legal pleadings. With the advance of information and its processing, means to gather the data are also evolving. …

WCF 第四章 绑定 netMsmqBinding

MSMQ 为使用队列创建分布式应用程序提供支持。WCF支持将MSMQ队列作为netMsmqBinding绑定的底层传输协议的通信。 netMsmqBinding绑定允许客户端直接把消息提交到一个队列中同时服务端从队列中读取消息。客户端和服务端之间没有直接通信过程&#xff1b;因此&#xff0c;通信本 …