查询表达式和LINQ to Objects
查询表达式实际上是由编译器“预处理”为“普通”的C#代码,接着以完全普通的方式进行编译。这种巧妙的发式将查询集合到了语言中,而无须把语义改得乱七八糟


#region 11-1打印出所有用户的袖珍查询
var query = from user in SampleData.AllUsers
select user;
foreach (var user in query)
{
Console.WriteLine(user);
}
#endregion
#region 11-2将11-1的查询表达式被转译为一个方法调用
var query = SampleData.AllUsers.Select(user => user);//编译器不要求Select必须为一个方法,或AllUsers必须为属性,只要转换后的代码可以编译就可以了
foreach (var user in query)
{
Console.WriteLine(user);
}
#endregion
#region 11-3编译器转译调用伪LINQ实现中的方法
static class Extensions
{
public static Dummy<T> Where<T>(this Dummy<T> dummy, Func<T, bool> predicate)//声明Where扩展方法
{
Console.WriteLine("Where called");
return dummy;
}
}
class Dummy<T>
{
public Dummy<U> Select<U>(Func<T, U> selector)//声明Select实例方法
{
Console.WriteLine("Select called");
return new Dummy<U>();
}
}
#endregion
#region 11-3
var source = new Dummy<string>();//创建用于查询的数据源
var query = from dummy in source
where dummy.ToString() == "Ignored"
select "Anything";//通过查询表达式来调用方法var query=source.where(dummy=>dummy.ToString()=="Ignored").Select(dummy=>"Anything")
#endregion

#region 11-4仅选择user对象名称的查询
IEnumerable<string> query = from user in SampleData.AllUsers
select user.Name;
foreach (string name in query)
{
Console.WriteLine(name);
}
#endregion
#region 11-5使用Cast和OfType来处理弱类型集合
ArrayList list = new ArrayList { "First", "Second", "Third" };
IEnumerable<string> strings = list.Cast<string>();
foreach (string item in strings)
{
Console.WriteLine(item);
}
list = new ArrayList { 1, "First", 'd', "dsds", 3 };
strings = list.OfType<string>();
foreach (string item in strings)
{
Console.WriteLine(item);
}
#endregion
#region 11-6使用显示类型的范围变量来自动调节Cast
ArrayList list = new ArrayList { "First", "Second", "Third" };
var strings = from string entry in list
select entry.Substring(0, 3);//IEnumerable<string> strings = from entry in source.Cast<string>() select entry.Substring(0, 3);
foreach (string start in strings)
{
Console.WriteLine(start);
}
#endregion
- LINQ以数据序列为基础,在任何可能的地方都进行流处理
- 创建一个查询并不会执行它:大部分操作都是延迟执行
- C#3的查询表达式包括一个把表达式转换为普通C#代码的预处理阶段,接着使用类型推断,重载,Lambda表达式等这些常规的规则来恰当的对转换后的代码进行编译
- 在查询表达式中声明的变量的作用:它们仅仅是范围变量,通过它们你可以查询表达式内部一直的引用数据
对序列进行过滤和排序
#region 11-7使用多个where字句的查询表达式
User tim = SampleData.Users.TesterTim;
var query = from defect in SampleData.AllDefects
where defect.Status != Status.Closed
where defect.AssignedTo == tim
select defect.Summary;
foreach (var summary in query)
{
Console.WriteLine(summary);
}
#endregion
#region 11-8按缺陷严重度的优先级从高到低的顺序排序
User tim = SampleData.Users.TesterTim;
var query = from defect in SampleData.AllDefects
where defect.Status != Status.Closed
where defect.AssignedTo == tim
orderby defect.Severity descending
select defect;
foreach (var defect in query)
{
Console.WriteLine("{0},{1}", defect.Severity, defect.Summary);
}
#endregion
#region 11-9先按严重度排序,而后按最后修改时间排序
User tim = SampleData.Users.TesterTim;
var query = from defect in SampleData.AllDefects
where defect.Status != Status.Closed
where defect.AssignedTo == tim
orderby defect.Severity descending, defect.LastModified
select defect;
foreach (var defect in query)
{
Console.WriteLine("{0},{1}({2:d})", defect.Severity, defect.Summary, defect.LastModified);
}
#endregion
#region 11-10在不使用let子句的情况下,按用户名称长度来排序
var query = from user in SampleData.AllUsers//两次使用了Length
orderby user.Name.Length
select user.Name;
foreach (var name in query)
{
Console.WriteLine("{0}:{1}", name.Length, name);
}
#endregion
#region 11-11使用let子句来消除冗余的计算
var query = from user in SampleData.AllUsers
let length = user.Name.Length//引入length范围变量
orderby length
select new { Name = user.Name, Length = length };
foreach (var name in query)
{
Console.WriteLine("{0}:{1}", name.Name, name.Length);
}
#endregion
#region 11-12根据项目把缺陷和通知订阅连接在一起
var query = from defect in SampleData.AllDefects
join subscription in SampleData.AllSubscriptions
on defect.Project equals subscription.Project
select new { defect.Summary, subscription.EmailAddress };
foreach (var entry in query)
{
Console.WriteLine("{0}:{1}", entry.EmailAddress, entry.Summary);
}
#endregion
#region 11-13使用分组连接把缺陷的订阅连接到一起
var query = from defect in SampleData.AllDefects
join subscription in SampleData.AllSubscriptions
on defect.Project equals subscription.Project
into gtoupedSubscription
select new { Defece = defect, Subscription = gtoupedSubscription };
foreach (var enrty in query)
{
Console.WriteLine(enrty.Defece.Summary);
foreach (var subscription in enrty.Subscription)
{
Console.WriteLine("{0}", subscription.EmailAddress);
}
}
#endregion
#region 11-15用户和项目的交叉连接
var query = from user in SampleData.AllUsers
from project in SampleData.AllProjects
select new { User = user, Project = project };
foreach (var pair in query)
{
Console.WriteLine("{0}/{1}", pair.User.Name, pair.Project.Name);
}
#endregion
#region 11-16右边序列依赖于左边元素的交叉连接
var query = from left in Enumerable.Range(1, 4)
from right in Enumerable.Range(11, left)
select new { Left = left, Right = right };
foreach (var pair in query)
{
Console.WriteLine("Left={0};Rigth={1}", pair.Left, pair.Right);
}
#endregion
#region 11-17用分配来分组缺陷——无比简单的投影
var query = from defect in SampleData.AllDefects
where defect.AssignedTo != null//过滤未分配的缺陷
group defect by defect.AssignedTo;//用分配者来分组
foreach (var entry in query)
{
Console.WriteLine(entry.Key.Name);
foreach (var defect in entry)
{
Console.WriteLine("({0}) {1}", defect.Severity, defect.Summary);
}
Console.WriteLine();
}
#endregion
#region 11-18按分配者来分组缺陷——投影只保留概要信息
var query = from defect in SampleData.AllDefects
where defect.AssignedTo != null
group defect.Summary by defect.AssignedTo;
foreach (var entry in query)
{
Console.WriteLine(entry.Key.Name);
foreach (var summary in entry)
{
Console.WriteLine(" {0}", summary);
}
Console.WriteLine();
}
#endregion
#region 11-19使用另外一个投影来延续分组结果
var query = from defect in SampleData.AllDefects
where defect.AssignedTo != null
group defect by defect.AssignedTo into grouped
select new { Assignee = grouped.Key, Count = grouped.Count() };//在第二部分使用grouped范围变量,不过defect范围变量不在可用——它已经超出了它的作用域
foreach (var entry in query)
{
Console.WriteLine("{0}:{1}", entry.Assignee.Name, entry.Count);
}
#endregion
#region 11-20在group和select子句之后的查询表达式延续
var query = from defect in SampleData.AllDefects
where defect.AssignedTo != null
group defect by defect.AssignedTo into grouped
select new
{
Assignee = grouped.Key,
Count = grouped.Count()
} into result
orderby result.Count descending
select result;
foreach (var entry in query)
{
Console.WriteLine("{0}:{1}", entry.Assignee.Name, entry.Count);
}
#endregion
#region 只能用于点标记操作
var que = SampleData.AllUsers.Where(I1 => I1.Name.Length % 2 == 0).Select((I1, I2) => new { I1, I2 });
foreach (var entry in que)
{
Console.WriteLine(entry.I2);
}
Console.WriteLine();
foreach (var entry in que)
{
Console.WriteLine(entry.I1);
}
Console.ReadKey();
#endregion
查询表达式和LINQ to Objects的更多相关文章
- 十五、C# 使用查询表达式的LINQ
使用查询表达式的LINQ 本章介绍了一种新的语法,查询表达式. 1.查询表达式概述 2.特点:投射 筛选 排序 Let 分组 3.作为方法调用 标准查询运算符所实现的查询在功能上 ...
- C#复习笔记(4)--C#3:革新写代码的方式(查询表达式和LINQ to object(下))
查询表达式和LINQ to object(下) 接下来我们要研究的大部分都会涉及到透明标识符 let子句和透明标识符 let子句不过是引入了一个新的范围变量.他的值是基于其他范围变量的.let 标识符 ...
- 《C#本质论》读书笔记(15)使用查询表达式的LINQ
15.1 查询表达式的概念 简单的查询表达式 private static void ShowContextualKeywords1() { IEnumerable<string> sel ...
- 2.1 LINQ的查询表达式
在进行LINQ查询的编写之前,首先需要了解查询表达式.查询表达式是LINQ查询的基础,也是最常用的编写LINQ查询的方法. 查询表达式由查询关键字和对应的操作数组成的表达式整体.其中,查询关键字是常用 ...
- Linq之旅:Linq入门详解(Linq to Objects)
示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细介绍 .NET 3.5 中引入的重要功能:Language Integrated Query(LINQ,语言集 ...
- Linq之旅:Linq入门详解(Linq to Objects)【转】
http://www.cnblogs.com/heyuquan/p/Linq-to-Objects.html Linq之旅:Linq入门详解(Linq to Objects) 示例代码下载:Linq之 ...
- Linq之旅:Linq入门详解(Linq to Objects)(转)
http://www.cnblogs.com/heyuquan/p/Linq-to-Objects.html 示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细 ...
- Linq查询表达式
目录 1. 概述 2. from子句 3. where子句 4. select子句 5. group子句 6. into子句 7. 排序子句 8. let子句 9. join子句 10. 小结 1. ...
- Linq学习之旅——LINQ查询表达式
1. 概述 2. from子句 3. where子句 4. select子句 5. group子句 6. into子句 7. 排序子句 8. let子句 9. join子句 10. 小结 1. 概述 ...
随机推荐
- Android Handler消息机制不完全解析
1.Handler的作用 Android开发中,我们经常使用Handler进行页面的更新.例如我们需要在一个下载任务完成后,去更新我们的UI效果,因为AndroidUI操作不是线程安全的,也就意味着我 ...
- Java实现读取文章中重复出现的中文字符串
在上个星期阿里巴巴一面的时候,最后面试官问我如何把一篇文章中重复出现的词或者句子找出来,当时太紧张,答的不是很好.今天有时间再来亲手实现一遍.其实说白了也就是字符串的处理,所以难度并不是很大. 以下是 ...
- servlet中的过滤器 国际化
1. 过滤器 基本概念 过滤器是需要在xml中配置的. 为什么需用到过滤器? 项目开发中,经常会涉及到重复代码的实现! 注册 ----à Servlet [1. 设置编码] ----à JSP 修改 ...
- 梳理一下web总的一些概念
servlet中的类适合繁复翻看文档,熟悉各个类的常用方法,看一些经典的案例代码. ServletConfig 每个项目有多个servlet,每个servlet对应一个ServletCOnfigt对象 ...
- ArrayList去除重复元素(包括字符串和自定义对象)
1.去除重复字符串 package com.online.msym; import java.util.ArrayList; import java.util.Iterator; @SuppressW ...
- java学习笔记 --- StringBuffer类
1.定义:字符串缓冲区,即它是一个容器,容器中可以装很多字符.并且能够对其中的字符进行各种操作. StringBuffer的特点: 1.是一个字符串缓冲区,其实就是一个容器. 2.长度是可变,任意类型 ...
- Windows下检测文件名大小写是否匹配
跨平台开发有一个众所周知,但因为只是偶尔受到困扰,一般人不会在意的问题,就是windows对文件名大小写不敏感,而其他平台对文件名大小写敏感.因此可能出现在windows平台开发时一切正常,但部署/打 ...
- POPTEST 150801 祝大家前途似锦
POPTEST 150801 祝大家前途似锦 PT20150801学员不断在就业,同学们走好,远兵辛苦了!!!
- html实现 页面禁止右键 禁止复制 禁止图片拖动 禁止复制和剪切
众所周知,一般的屏蔽的方法是用JS来编写的脚本,但是也可以直接通过修改网页属性的方法来屏蔽右键 禁止复制. 禁止右键 oncontextmenu="return false" 禁止 ...
- (转)Java并发编程:并发容器之ConcurrentHashMap
下面这部分内容转载自: http://www.haogongju.net/art/2350374 JDK5中添加了新的concurrent包,相对同步容器而言,并发容器通过一些机制改进了并发性能.因为 ...