一、标准查询运算符

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# 标准查询表达式的更多相关文章

  1. C#3.0新增功能09 LINQ 标准查询运算符 02 查询表达式语法

    连载目录    [已更新最新开发文章,点击查看详细] 某些使用更频繁的标准查询运算符具有专用的 C# 语言关键字语法,使用这些语法可以在查询表达式中调用这些运算符. 查询表达式是比基于方法的等效项更具 ...

  2. 《LINQ技术详解C#》-2.查询表达式翻译为标准查询操作符

    (1)透明标识符 有些翻译步骤要使用透明标识符(*)插入枚举变量. 透明标识符只在翻译过程中存在,翻译结束将不再出现. (2)翻译步骤 ①带有into连续语句的Select和Group语句 from. ...

  3. [C#] 进阶 - LINQ 标准查询操作概述

    LINQ 标准查询操作概述 序 “标准查询运算符”是组成语言集成查询 (LINQ) 模式的方法.大多数这些方法都在序列上运行,其中的序列是一个对象,其类型实现了IEnumerable<T> ...

  4. .NET中那些所谓的新语法之四:标准查询运算符与LINQ

    开篇:在上一篇中,我们了解了预定义委托与Lambda表达式等所谓的新语法,这一篇我们继续征程,看看标准查询运算符和LINQ.标准查询运算符是定义在System.Linq.Enumerable类中的50 ...

  5. Linq查询表达式

    目录 1. 概述 2. from子句 3. where子句 4. select子句 5. group子句 6. into子句 7. 排序子句 8. let子句 9. join子句 10. 小结 1. ...

  6. .NET LINQ标准查询运算符

    标准查询运算符概述      “标准查询运算符”是组成语言集成查询 (LINQ) 模式的方法. 大多数这些方法都在序列上运行,其中的序列是一个对象,其类型实现了 IEnumerable<T> ...

  7. LINQ 查询表达式(C# 编程指南)

    语言集成查询 (LINQ) 是一组技术的名称,这些技术建立在将查询功能直接集成到 C# 语言(以及 Visual Basic 和可能的任何其他 .NET 语言)的基础上.  借助于 LINQ,查询现在 ...

  8. 《C#本质论》读书笔记(14)支持标准查询操作符的集合接口

      14.2.集合初始化器 使用集合初始化器,程序员可以采用和数组相似的方式,在集合的实例化期间用一套初始的成员来构造这个集合. 如果没有集合初始化器,就只有在集合实例化后才能显示添加到集合中--例如 ...

  9. LinQ实战学习笔记(三) 序列,查询操作符,查询表达式,表达式树

    序列 延迟查询执行 查询操作符 查询表达式 表达式树 (一) 序列 先上一段代码, 这段代码使用扩展方法实现下面的要求: 取进程列表,进行过滤(取大于10M的进程) 列表进行排序(按内存占用) 只保留 ...

随机推荐

  1. JSP SQL注入

    Login.JSP <%@ page language="java" import="java.util.*" pageEncoding="UT ...

  2. Cocos2d-x 3.4版本 新建项目 IOS版

    打开终端 cd进入cocos2d-x-3.0/tools/cocos2d-console/bin 然后执行下面命令 ./cocos.py new testHuoFei -p com.huofei.ap ...

  3. 剑指Offer:面试题13——在O(1)时间删除链表结点

    问题描述: 给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点.链表结点与函数的定义如下: public class ListNode{ int value; ListNode ...

  4. 通过 adb命令发送广播

    我们经常用到模块设备发送广播,此处记录一下: 首先进入adb 使用命令: adb shell 发送广播 例: am broadcast -a action.com.custom.broadcast.q ...

  5. MySQL的体系结构

    因为MySQL采用的是客户机/服务器体系结构,所以你在使用MySQL存取数据时,必须至少使用两个或者说两类程序: 一个位于存放您的数据的主机上的程序 ----数据库服务器.数据库服务器监听从网络上传过 ...

  6. sql server数据库中 smallint, int ,bigint ,tinyint的区别与长度

    smallint  是一种精确的数值数据类型,其精度在算术运算后不变,采用2个字节编码 有符号的 smallint 值的范围是 -2^15-------2^15 -1,即 -32768 ----327 ...

  7. linux使用flock文件锁解决crontab冲突问题

    * * * * * flock -xn /dev/shm/redis.lock -c "/usr/local/bin/redis-server" 可以用flock命令,配合使用rs ...

  8. sublime Text及package control的安装

    1.下载并安装sublime Text2http://www.baidu.com/s?wd=sublime&rsv_spt=1&issp=1&f=8&rsv_bp=0& ...

  9. 操作笔记:tomcat在正式环境

    1,一台服务器有两个容器,比如:jetty,tomcat. 出现问题: jetty启动的时候,tomcat就不能启动了. 此时,需要修改tomcat的配置文件:servler.xml <?xml ...

  10. Vim与GCC和gdb完美组合

    一.vim vim修改一下配置文件后,如果你稍微会点vim的命令使用,那可比一般的编辑器好用啊,如果一点不会vim的命令使用,就跟一般编辑器一样使用. 打开etc/vim/vimrc文件 这里的引号是 ...