C# 标准查询表达式
一、标准查询运算符
1、C#提供了标准查询运算符,例如我想选择专利一系列(pantents)中以年份19开头的专利,可以用如下语句:
IEnumerable<Patent> pantentWhere = pantents.Where(pantent =>
pantent.YearOfPublicaton.StartsWith(""));
当然,此处的语句只是定义了查询,此时pantentWhere并没有内容,后面Lambda表达式指定的查询并没有执行,只有当遍历pantentWhere集合的时候才开始执行这个查询规则,这是C#中标准查询的“推迟执行”
2、投射
专利类包含了 名字 年份 应用号 发明者 等,如果我想将专利类的集合中 每个专利的类型都变为只包含 名字与年份的类型,那么可以使用select做到,代码如下:
var pantentSelect = pantents.Select(
pantent =>
{
return new
{
Title = pantent.Title,
Year = pantent.YearOfPublicaton
};
});
可以看到,Lambda表达式返回了一个包含 名字与年份的类型。而当遍历pantentSelect时,其投射语句执行,它则是有[(姓名,值),(年份,值)]构成的集合。
3、排序
利用标准查询运算符OrderByDescending 与 ThenByDescending 可以完成多条件的排序,代码如下:
IEnumerable<Patent> pantentOrder = pantents.OrderByDescending(pantent =>
pantent.YearOfPublicaton).ThenByDescending(
pantent => pantent.Title);
可以看到,只用了一个OrderBy,它会获取并且只会获取一个成为KeySelector的参数来排序,例如本例中的YearOfPublicaton。如果要继续按照第二个关键字排序,只能用ThenBy,在OrderBy的基础上执行。而连着使用多个OrderBy只会撤销上一个OrderBy,所以要用ThenBy,而不是继续使用OrderBy。
此处仅仅简单的列出几项,因为如果执行比较复杂的查询与投射,将会产生比较繁琐难懂的代码。因此,C# 3.0中引入了标准查询表达式,一种更类似于SQL语言的
二、标准查询表达式
1、简单示例,下段代码完成的功能是检索出不含有*的单词:
class Program
{
static string[] Keywords = { "*a", "*b", "*c", "*d", "*e", "*f", "a", "b", "c", "d", "e", "f", "g", "h", "i"};
static void Main(string[] args)
{
ShowContextualKeyword1();
}
public static void ShowContextualKeyword1()
{
IEnumerable<string> selection = from word in Keywords
where !word.Contains('*')
select word;
foreach (string s in selection)
{
Console.WriteLine(" " + s);
}
}
}
值得详细说一下的是类型推断:select投射回的是word的集合,word的类型是from后面的那个word,从Keywords推断得到。Keywords是一个string的集合,所以word是string类型,因此select投射到的是IEnumerable<string>
2、改变返回类型。
select不仅可以返回原始类型,也可以返回指定的类型,我个人总结的是 他会返回select后面的变量的集合类型。
如下代码,返回的不是fileName的集合,而是FileInfo的集合:
public static void List1(string rootDirectory, string searchPattern)
{
IEnumerable<FileInfo> files = from fileName in Directory.GetFiles(rootDirectory, searchPattern)
select new FileInfo(fileName);
foreach (FileInfo file in files)
{
Console.WriteLine(".{0}({1})",file.Name,file.LastWriteTime);
}
}
当然,3.0允许程序员不必显示声明投射的类型,而可以使用匿名类型,如下代码所示:
public static void List2(string rootDirectory, string searchPattern)
{
var files = from fileName in Directory.GetFiles(rootDirectory, searchPattern)
select new
{
Name = fileName,
LastWriteTime = File.GetLastWriteTime(fileName)
};
foreach (var file in files)
{
Console.WriteLine(".{0}({1})", file.Name, file.LastWriteTime);
}
}
如果select的原始数据的列特别多,改变投射类型则显得十分有优势,只需选出需要关注的几列即可,而不用全部都检索出来。
3、筛选(where)
筛选条件靠断言来表示,即返回布尔值的一个,真就接受,假就放弃。代码如下,功能是筛选出一个月之前修改的文件:
static void FindMonthOldFiles(string rootDirectory, string searchPattern)
{
// 筛选出一个月之前访问的数据
IEnumerable<FileInfo> files = from fileName in Directory.GetFiles(rootDirectory, searchPattern)
where File.GetLastWriteTime(fileName) < DateTime.Now.AddMonths(-)
select new FileInfo(fileName);
foreach (FileInfo file in files)
{
string relativePath = file.FullName.Substring();
Console.WriteLine(".{0}.({1})", relativePath, file.LastWriteTime);
}
}
4、排序
下面代码展示了一种排序:首先按照文件名长度降序排序,然后按照文件名升序排序(不显示声明升序还是降序的,默认升序):
IEnumerable<string> fileNames = from fileName in Directory.GetFiles(rootDirectory,searchPattern)
orderby (new FileInfo(fileName)).Length descending,fileName
select fileName;
多个排序条件用逗号隔开,重要性依次降低。但是如果我想投射一个FileInfo的集合怎么办呢?可能会有如下代码:
IEnumerable<FileInfo> fileNames = from fileName in Directory.GetFiles(rootDirectory,searchPattern)
orderby (new FileInfo(fileName)).Length descending,fileName
select new FileInfo(fileName);
那么问题来了。看第2行与第3行,这样写会每一次访问,都会实例化两个FileInfo,十分浪费系统资源,于是C#3.0隆重推出了let字句。
5、let子句
let 子句添加的表达式可以在整个查询表达式的范围内使用,从而避免重复实例化,写法如下:
IEnumerable<FileInfo> fileNames = from fileName in Directory.GetFiles(rootDirectory,searchPattern)
let file = new FileInfo(fileName)
orderby file.Length descending, fileName
select file;
6、编译
实际上,使用查询运算符与查询表达式对CIL CLR没有影响,编译器会将查询表达式转化成标准查询运算符。虽然属于语法糖级别的,但是平时尽可能多使用查询表达式,除非在某些特定情况下,再使用标准查询运算符。
C# 标准查询表达式的更多相关文章
- C#3.0新增功能09 LINQ 标准查询运算符 02 查询表达式语法
连载目录 [已更新最新开发文章,点击查看详细] 某些使用更频繁的标准查询运算符具有专用的 C# 语言关键字语法,使用这些语法可以在查询表达式中调用这些运算符. 查询表达式是比基于方法的等效项更具 ...
- 《LINQ技术详解C#》-2.查询表达式翻译为标准查询操作符
(1)透明标识符 有些翻译步骤要使用透明标识符(*)插入枚举变量. 透明标识符只在翻译过程中存在,翻译结束将不再出现. (2)翻译步骤 ①带有into连续语句的Select和Group语句 from. ...
- [C#] 进阶 - LINQ 标准查询操作概述
LINQ 标准查询操作概述 序 “标准查询运算符”是组成语言集成查询 (LINQ) 模式的方法.大多数这些方法都在序列上运行,其中的序列是一个对象,其类型实现了IEnumerable<T> ...
- .NET中那些所谓的新语法之四:标准查询运算符与LINQ
开篇:在上一篇中,我们了解了预定义委托与Lambda表达式等所谓的新语法,这一篇我们继续征程,看看标准查询运算符和LINQ.标准查询运算符是定义在System.Linq.Enumerable类中的50 ...
- Linq查询表达式
目录 1. 概述 2. from子句 3. where子句 4. select子句 5. group子句 6. into子句 7. 排序子句 8. let子句 9. join子句 10. 小结 1. ...
- .NET LINQ标准查询运算符
标准查询运算符概述 “标准查询运算符”是组成语言集成查询 (LINQ) 模式的方法. 大多数这些方法都在序列上运行,其中的序列是一个对象,其类型实现了 IEnumerable<T> ...
- LINQ 查询表达式(C# 编程指南)
语言集成查询 (LINQ) 是一组技术的名称,这些技术建立在将查询功能直接集成到 C# 语言(以及 Visual Basic 和可能的任何其他 .NET 语言)的基础上. 借助于 LINQ,查询现在 ...
- 《C#本质论》读书笔记(14)支持标准查询操作符的集合接口
14.2.集合初始化器 使用集合初始化器,程序员可以采用和数组相似的方式,在集合的实例化期间用一套初始的成员来构造这个集合. 如果没有集合初始化器,就只有在集合实例化后才能显示添加到集合中--例如 ...
- LinQ实战学习笔记(三) 序列,查询操作符,查询表达式,表达式树
序列 延迟查询执行 查询操作符 查询表达式 表达式树 (一) 序列 先上一段代码, 这段代码使用扩展方法实现下面的要求: 取进程列表,进行过滤(取大于10M的进程) 列表进行排序(按内存占用) 只保留 ...
随机推荐
- JSP SQL注入
Login.JSP <%@ page language="java" import="java.util.*" pageEncoding="UT ...
- Cocos2d-x 3.4版本 新建项目 IOS版
打开终端 cd进入cocos2d-x-3.0/tools/cocos2d-console/bin 然后执行下面命令 ./cocos.py new testHuoFei -p com.huofei.ap ...
- 剑指Offer:面试题13——在O(1)时间删除链表结点
问题描述: 给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点.链表结点与函数的定义如下: public class ListNode{ int value; ListNode ...
- 通过 adb命令发送广播
我们经常用到模块设备发送广播,此处记录一下: 首先进入adb 使用命令: adb shell 发送广播 例: am broadcast -a action.com.custom.broadcast.q ...
- MySQL的体系结构
因为MySQL采用的是客户机/服务器体系结构,所以你在使用MySQL存取数据时,必须至少使用两个或者说两类程序: 一个位于存放您的数据的主机上的程序 ----数据库服务器.数据库服务器监听从网络上传过 ...
- sql server数据库中 smallint, int ,bigint ,tinyint的区别与长度
smallint 是一种精确的数值数据类型,其精度在算术运算后不变,采用2个字节编码 有符号的 smallint 值的范围是 -2^15-------2^15 -1,即 -32768 ----327 ...
- linux使用flock文件锁解决crontab冲突问题
* * * * * flock -xn /dev/shm/redis.lock -c "/usr/local/bin/redis-server" 可以用flock命令,配合使用rs ...
- sublime Text及package control的安装
1.下载并安装sublime Text2http://www.baidu.com/s?wd=sublime&rsv_spt=1&issp=1&f=8&rsv_bp=0& ...
- 操作笔记:tomcat在正式环境
1,一台服务器有两个容器,比如:jetty,tomcat. 出现问题: jetty启动的时候,tomcat就不能启动了. 此时,需要修改tomcat的配置文件:servler.xml <?xml ...
- Vim与GCC和gdb完美组合
一.vim vim修改一下配置文件后,如果你稍微会点vim的命令使用,那可比一般的编辑器好用啊,如果一点不会vim的命令使用,就跟一般编辑器一样使用. 打开etc/vim/vimrc文件 这里的引号是 ...