LINQ基础教程 LINQ基础教程 主讲人:李春涛 徐卫东.

Slides:



Advertisements
Similar presentations
第二章 简单的 SQL 语句. 本章要点  创建一个简单的表  SQL 语句介绍  最简单的查询语句 select  带有限制条件的查询  查询结果的排序显示.
Advertisements

第6章 数据库管理软件Access 年秋.
目 录 第 1 章 数据库技术基础 第 2 章 SQL Server基础 第 3 章 数据库管理 第 4 章 查询和视图
SQL的简单查询.
第八讲 基于Hadoop的数据仓库Hive (PPT版本号:2016年4月6日版本)
第2讲 Transact-SQL语言.
数据库技术 实践.
高等院校计算机教材系列 数据库原理与应用(第2版) 任课教师:刘雅莉
第2章 数据模型 2.1 实体联系模型 2.2 关系模型 2.3 面向对象的数据模型 习 题 2.
C#程序设计案例教程 第3章 程 序 结 构.
文科计算机小公共课规划教材 Access 程序设计.
在线考试系统 答辩人: 朱允昌、朱碧云、张海燕 汇报时间: 指导老师: 任艳、徐怡 软件应用与开发类
C#程序设计 10软件1、2班 王槐彬 计算机工程学院.
Google App Engine Google 應用服務引擎.
鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所
C# 程式設計 第一部分 第1-4章 C# 程式設計 - 南華大學資管系.
關聯式資料庫.
BLANK overview.
第六章 學習SQL語言.
9 SELECT敘述的進階查詢 9-1 SQL的多資料表查詢 9-2 合併查詢 9-3 集合運算查詢 9-4 子查詢
Visual C# 2010 程式設計經典 第15章 ADO .NET與資料工具.
LINQ 建國科技大學 資管系 饒瑞佶.
第二章 C# 基础知识.
基于Hadoop的数据仓库Hive.
2、掌握SQL中各种查询方法和数据更新方法 3、掌握SQL中视图的定义方法和用法 4、掌握SQL的授权机制
卢斌 Software Development Engineer Microsoft Corporation
DEV 331 深度探索 Microsoft Visual C# 2.0
第9讲 Hibernate查询语言HQL.
程式敘述執行順序的轉移 控制與重複、方法 Lecturer:曾學文.
電子商務網站建制技術與實習(II) 助教:江宜政 吳昇洋.
第20章 LINQ 資料查詢技術 注意: 本投影片僅供本書上課教師使用,非經同意請勿上網轉載或拷貝.
第2章 ADO.NET 2.0概述.
第4章(2) 空间数据库 —关系数据库 北京建筑工程学院 王文宇.
JAVA程序设计 第5章 深入理解JAVA语言----补充.
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
实验 2:MS Access QBE Query使用
鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所
第九章 進階的查詢技巧.
第4章 数组和集合 4.1 一维数组 4.2 二维数组 4.3 Array类 4.4 交错数组 4.5 ArrayList类
第三章 流程控制與例外處理 資訊教育研究室 製作 注意:本投影片僅供上課使用,非經同意,請勿散播或轉載。
国家“十一五”规划教材 数据库原理与应用教程(第3版).
SQL SERVER 一些经典语句 1.
复习 JavaScript && ES6 专题 (1) 2017/3/10 – Payne
MySQL 結構化查詢語言 MySQL.
例外處理與 物件序列化(Exception Handling and Serialization of Objects)
泛型委托 泛型接口、方法和委托.
第 8 章 VB.NET与数据库应用程序 本章主要内容: ADO.NET体系结构; VB.NET与SQL Server数据库的连接;
Spark SQL 介绍 付士涛. Spark SQL 介绍 付士涛 大纲 Architecture(架构) 像Hive一样的User Interface(用户操作界面) DataFrame的使用(1.3以前叫做SchemaRDD)
編譯程式設計 期末專題說明 V1.1 May 2004.
第三章 C# 基础知识.
<title> XML與XQuery ,新一代資料儲存標準 </title>
第五讲 酒店客房管理系统(一) 教育部“十二五”职业教育国家规划教材
数据库技术.
第18章 SQL結構化查詢語言 18-1 SQL語言的基礎 18-2 SQL的查詢指令 18-3 SQL子查詢與合併查詢.
第五章 介面/集合/泛型 注意: 本投影片僅供本書上課教師使用,非經同意請勿上網轉載或供拷貝.
資料庫系統 李翊豪 2017/12/21 Reference
补充:c#语言基础.
21世纪高职高专规划教材 C#语言程序设计 李继武 彭德林 主 编 张 珑 赵 松 周建辉 副主编
3. SQL语言的应用 3.1 SQL历史和优点 3.2 数据查询 3.3 数据操纵.
查询与视图 蔡海洋.
SQL查询语句 蔡海洋.
OrientX3.0及其改进之处 XML小组.
第二章 Java语法基础.
本章要点: 了解ASP.NET 4.5的基础.NET Framework。
Ch16. 協定.
LINQ 語法簡介 設計人:顏嘉君.
第二章 Java基本语法 讲师:复凡.
数据分析工具 第10节.
C#快速導讀 流程控制.
第4章 数据查询.
Presentation transcript:

LINQ基础教程 LINQ基础教程 主讲人:李春涛 徐卫东

1 3 2 学习目标 LINQ基本概念的掌握 LINQ查询方法及项目中的应用 LINQ进阶 1、基本概念: 理解查询语句与查询方法的关系 掌握各种高级查询方法

1 LINQ基本概念的掌握 设计、组织和协作

LINQ是Language Integrated Query的简称。是 Visual Studio 2008 和 LINQ是Language Integrated Query的简称。是 Visual Studio 2008 和 .NET Framework 3.5 版中一项突破性的创新,它在对象领域和数据领域之间架起了一座桥梁。 微软在2007年,将LINQ作为.NET Framework 3.5的一部分正式发布,编写程序时可以得到很好的编译时语法检查,丰富的元数据,智能感知、静态类型等强类型语言的好处。 Linq目标是实现语言与数据的深度结合,Linq以统一的数据访问方式访问各种数据源,以相同的方式读取数据,象SQL语句一样进行查询,而这些都是整合在我们熟悉的编程语言C#当中,另外Linq是使用强类型,并提供编译时检查和VS的智能感知特性等。 通过使用查询语法,可以使用最少的代码对数据源执行复杂的筛选、排序和分组操作。 举例:分组

LINQ包括五个部分:LINQ to Objects、LINQ to DataSets、LINQ to SQL、LINQ to Entities、LINQ to XML。 LINQ to Objects在当前项目中应用最为频繁,是我们可以简单的对内存中所有基于IEnumerable<T>接口的数据源进行操作。 LINQ to SQL全称基于关系数据的.NET语言集成查询,用于以对象形式管理关系数据,并提供了丰富的查询功能。其建立于公共语言类型系统中的基于SQL的模式定义的集成之上,当保持关系型模型表达能力和对底层存储的直接查询评测的性能时,这个集成在关系型数据之上提供强类型。 LINQ to XML在System.Xml.LINQ命名空间下实现对XML的操作。采用高效、易用、内存中的XML工具在宿主编程语言中提供XPath/XQuery功能等。 LINQ已成为编程语言的一个组成部分,在编写程序时可以得到很好的编译时语法检查,丰富的元数据,智能感知、静态类型等强类型语言的好处。并且它同时还使得查询可以方便地对内存中的信息进行查询而不仅仅只是外部数据源。 LINQ定义了一组标准查询操作符用于在所有基于.NET平台的编程语言中更加直接地声明跨越、过滤和投射操作的统一方式,标准查询操作符允许查询作用于所有基于IEnumerable<T>接口的数据源。

LINQ的组成 不同的部分会应用不同的provider,

与LINQ相关的概念 扩展方法  其实仅仅是语法糖,没有扩展方法,Linq的实现肯定不会再像现在这么优雅。从IL层面解释扩展方法的实现,它最终还是调用静态方法。 匿名方法和Lambda表达式  Lambda表达式将函数式编程风格带进了C#这种命令编程语言中,Lambda表达式可以编译成表达式树。 匿名类型与隐式类型局部变量(var) 如果没有隐式类型局部变量,使用Linq查询的时候不会再像现在这么轻松吧. var KeyPair1 = new { Key="yuyi",Value="Programer"}; 匿名类型在编译阶段编译器就为匿名类型生成了类型的代码,但是生 成的是泛型版本的 对象集合初始化器 编译器会调用无参构造函数,然后为指定的属性赋值。对匿名类型来说是很有用的。 LINQ是在ADO.NET之上的,那么在将来它会代替ADO.NET吗? 在大型项目中使用LINQ,它的效率如何呢? 表达式树是LINQ TO SQL的基础。 1、扩展方法是一种特殊的静态方法(优先级比实力方法底) 2、扩展方法必须在静态类中定义 3、扩展方法的优先级低于同名的类方法 4、不要滥用扩展方法—会造成代码污染? 表达式树就是一种表示表达式的数据结构

// 根据书籍分类获取书籍列表 var booksByCategory = from book in db.Books where book.Category.Name == categoryName select new { Title = book.Title, Author = book.Author, PublisherName = book.Publisher.Name, PublishDate = book.PublishDate, }; var booksByCategoryAndPage = booksByCategory.Skip((pageNo - 1) * PAGE_SIZE).Take(PAGE_SIZE); int pageCount = booksByCategory.Count() / PAGE_SIZE + 1; gvBooks.DataSource = booksByCategoryAndPage; gvBooks.DataBind();

2 LINQ进阶

LINQ查询执行的时机 1、查询分为以下三步:获取数据源、定义查询、执行查询 2、定义查询后,查询直到需要枚举结果时才被真正执行,成为延迟执行;举例 3、当查询方法返回单一值时,查询立即执行。Count()方法 4、可以使用ToList()或ToArray()方法强制立即执行

1、Method Syntax,查询方法方式 LINQ的查询方式 1、Method Syntax,查询方法方式 主要利用System.Linq.Enumberable类中定义的扩展方法和Lambda表达式进行查询。 2、Query Syntax,查询语句方式 一种更接近SQL语法的查询方式,具有更好的可读性。 查询语句与查询方法存在着紧密的关系 CLR本身并不理解查询语句,它只理解查询方法 编译器负责在编译时将查询语句翻译为查询方法 大部分查询方法都有对应的查询语句形式:如 Select() 对应 select 、 OrderBy() 对应 orderby 部分查询方法目前在C#中还没有对应的查询语句:如 Count()和Max() 这时只能采用以下替代方案 查询方法 查询语句 + 查询方法的混合方式; 一般情况下,建议使用可读性更好的查询语句

int[] numbers = new int[] { 6, 4, 3, 2, 9, 1, 7, 8, 5 }; var even = from number in numbers where number % 2 == 0 orderby number descending select number; 查询语句 两者的执行效果完全一样 int[] numbers = new int[] { 6, 4, 3, 2, 9, 1, 7, 8, 5 }; var even = numbers .Where(p => p % 2 == 0) .OrderByDescending(p => p) .Select(p => p); 注意说明大部分查询方法都有对应的查询语句 查询语句与查询方法存在着紧密的关系 CLR本身并不理解查询语句,它只理解查询方法 编译器负责在编译时将查询语句翻译为查询方法 大部分查询方法都有对应的查询语句形式:如 Select() 对应 select 、 OrderBy() 对应 orderby 部分查询方法目前在C#中还没有对应的查询语句:如 Count()和Max() 这时只能采用以下替代方案 查询方法 查询语句 + 查询方法的混合方式; 一般情况下,建议使用可读性更好的查询语句 查询方法

表达式树 1、什么是表达式树? 它是一种抽象语法树或者说它是一种数据结构,通过解析表达式目录树,可以实现我们一些特定的功能,它是LINQ Provider的基础。 我们将Lambda表达式指定给Expression<TDelegate>类型的变量(参数)时,编译器将会发出生成表达式目录树的指令,如上面这段代码中的Lambda表达式(a, b) => a * b + 2将创建一个表达式目录树,它表示的是一种数据结构,即我们把一行代码用数据结构的形式表示了出来,具体来说最终构造出来的表达式目录树形状如下图所示

2、如何构造出表达式目录树 Expression<Func<int, int, int>> expression = (a, b) => a * b + 2; 简单的表达式树,编译器会将表达式用树状的数据结构存储起来

LINQ TO SQL 表达式树 为什么需要表达式树? 当我们在C#中编写一个查询表达式时, 它将返回一个IQueryable类型的值,在该类型中包含了 两个很重要的属性Expression和Provider 查询表达式,将封装为一种抽象的数据结构,这个数据结构就是表达式目录树,当我们在使用上面返回的值时,编译器将会以该值所期望的方式进行翻译,这种方式就是由Expression和Provider来决定。可以看到,这样将会非常的灵活且具有良好的可扩展性,有了表达式目录树,可以自由的编写自己的Provider,去查询我们希望的数据源。经常说LINQ为访问各种不同的数据源提供了一种统一的编程方式,其奥秘就在这里。 INQ to Excel LINQ to Expressions (MetaLinq) LINQ Extender (Toolkit for building LINQ Providers) LINQ to Flickr LINQ to Google LINQ to Indexes (LINQ and i40) LINQ to IQueryable (Matt Warren on Providers) LINQ to JSON LINQ to LDAP LINQ to NHibernate LINQ to JavaScript LINQ to Lucene LINQ to Metaweb(freebase) LINQ to MySQL, Oracle and PostgreSql LINQ to RDF Files LINQ to Sharepoint LINQ to SimpleDB

3 LINQ查询方法及 项目中的应用 一个Linq例子 Linq语法基础 Linq语法的本质 Linq语言要素

一个Linq例子

一个Linq例子 var words = from word in "The quick brown fox jumps over the lazy dog".Split() orderby word.ToUpper() select word;

一个Linq例子 运行结果:

Linq语法基础

Linq语法基础 Where的声明: public static IEnumerable<TSource> Where<TSource>( this IEnumerable<TSource> source, Func<TSource, bool> predicate )

Linq语法基础 string[] names = { "Tom", "Dick", "Harry" }; IEnumerable<string> filteredNames = System.Linq.Enumerable.Where (names, n => n.Length >= 4); 运行结果:

Linq语法基础 String[] names = { "Tom", "Dick", "Harry" }; IEnumerable<string> result = names.Where(n=>n.Length >=4); 运行结果:

总结 Extension Method是一个定义在Static Class的一个特殊的Static Method。之所以说这个Static Method特别,是因为Extension Method不但能按照Static Method的语法进行调用,还能按照Instance Method的语法进行调用。

Linq语法的本质

Linq语法的本质 string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" }; IEnumerable<string> query1 = from name in names where name.Contains("a") orderby name.Length select name.ToUpper();

Linq语法的本质 运行结果:

Linq语法的本质 string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" }; IEnumerable<string> query = names .Where (n => n.Contains ("a")) .OrderBy (n => n.Length) .Select (n => n.ToUpper());

Linq语法的本质 运行结果:

Linq语法的本质 string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" }; IEnumerable<string> filtered = names.Where (n => n.Contains ("a")); IEnumerable<string> sorted = filtered.OrderBy (n => n.Length); IEnumerable<string> finalQuery = sorted.Select (n => n.ToUpper());

Linq语法的本质 string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" }; IEnumerable<string> filtered = names.Where (n => n.Contains ("a"));

Linq语法的本质 string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" }; IEnumerable<string> filtered = names.Where (n => n.Contains ("a")); IEnumerable<string> sorted = filtered.OrderBy (n => n.Length);

Linq语法的本质 运行结果:

Linq语法的本质 string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" }; IEnumerable<string> filtered = names.Where (n => n.Contains ("a")); IEnumerable<string> sorted = filtered.OrderBy (n => n.Length); IEnumerable<string> finalQuery = sorted.Select (n => n.ToUpper());

Linq语法的本质 运行结果:

Linq的语法,其实就是调用“扩展方法”的语法糖,Linq语句,最终都会转换成对相应的“扩展方法”的调用. 总结 Linq的语法,其实就是调用“扩展方法”的语法糖,Linq语句,最终都会转换成对相应的“扩展方法”的调用.

Linq语言要素

数据结构上的关联 public class Customer { public string Name; public string City; public Order[] Orders; } public class Order{ public int Quantity; public Product product; public class Product{ public string ProductName;

数据结构上的关联 Order[] ordersA = { new Order{Quantity = 10,product= new Product{ProductName = "PA1"}}, new Order{Quantity = 20,product = new Product{ProductName = "PA2"}}, new Order{Quantity =30,product = new Product{ProductName = "PA3"}} }; Order[] ordersB = { new Order{Quantity = 10,product= new Product{ProductName = "PB1"}}, new Order{Quantity = 20,product = new Product{ProductName = "PB2"}}, new Order{Quantity =30,product = new Product{ProductName = "PB3"}} Customer[] Customers = { new Customer{Name= "CA",City= "CityA",Orders =ordersA }, new Customer{Name = "CB",City = "CityB",Orders = ordersB}

var query = from c in Customers from o in c.Orders 数据结构上的关联 查询语句: var query = from c in Customers from o in c.Orders select new { c.Name, o.Quantity, o.product.ProductName }; foreach (var item in query){ Console.WriteLine(item.ToString()); }

{ Name = CA, Quantity = 10, ProductName = PA1 } 数据结构上的关联 运行结果: { Name = CA, Quantity = 10, ProductName = PA1 } { Name = CA, Quantity = 20, ProductName = PA2 } { Name = CA, Quantity = 30, ProductName = PA3 } { Name = CB, Quantity = 10, ProductName = PB1 } { Name = CB, Quantity = 20, ProductName = PB2 } { Name = CB, Quantity = 30, ProductName = PB3 }

数据结构上的关联2 var query = from c in Customers from o in c.Orders where o.Quantity == 20 select new { c.Name, o.Quantity, o.product.ProductName }; foreach (var item in query){ Console.WriteLine(item.ToString()); }

{ Name = CA, Quantity = 20, ProductName = PA2 } 数据结构上的关联2 运行结果: { Name = CA, Quantity = 20, ProductName = PA2 } { Name = CB, Quantity = 20, ProductName = PB2 }

数据结构上的关联3 var query = from c in Customers where c.Name.Contains("CA") from o in c.Orders where o.Quantity == 20 select new { c.Name, o.Quantity, o.product.ProductName }; foreach (var item in query){ Console.WriteLine(item.ToString()); }

{ Name = CA, Quantity = 20, ProductName = PA2 } 数据结构上的关联3 运行结果: { Name = CA, Quantity = 20, ProductName = PA2 }

数据结构上的关联3 var query = from c in Customers from o in c.Orders where c.Name.Contains("CA") where o.Quantity == 20 select new { c.Name, o.Quantity, o.product.ProductName }; where c.Name.Contains("CA") && o.Quantity == 20 以上两种Linq效果相同

public class Customer{ public string Name; public string City; } 数据上的关联 public class Customer{ public string Name; public string City; } public class Supplier{

数据上的关联 Customer[] Customers = { new Customer{City = "CA",Name = "CustA"}, new Customer{City = "CB",Name = "CustB"}, new Customer{City = "CC",Name = "CustC"}, new Customer{City = "CD",Name = "CustD"} }; Supplier[] Suppliers ={ new Supplier{City = "CA" ,Name = "SA"}, new Supplier{City = "CB" ,Name = "SB"}, new Supplier{City = "CC" ,Name = "SC"}, new Supplier{City = "CC" ,Name = "SD"}, new Supplier{City = "CC" ,Name = "SE"}

必须用equals关键字,不能用“==”比较 数据上的关联 必须用equals关键字,不能用“==”比较 var query = from c in Customers join s in Suppliers on c.City equals s.City select new { CCity =c.City, CName = c.Name,SCity= s.City,SName =s.Name }; foreach (var item in query){ Console.WriteLine(item.ToString()); }

数据上的关联 运行结果: { CCity = CA, CName = CustA, SCity = CA, SName = SA } { CCity = CB, CName = CustB, SCity = CB, SName = SB } { CCity = CC, CName = CustC, SCity = CC, SName = SC } { CCity = CC, CName = CustC, SCity = CC, SName = SD } { CCity = CC, CName = CustC, SCity = CC, SName = SE }

数据上的关联2 var query = from c in Customers join s in Suppliers on c.City equals s.City into customerSuppliers select new { CCity = c.City, CName = c.Name, customerSuppliers }; foreach (var item in query){ Console.WriteLine(string.Format("CCity = {0}, CName = {1},", item.CCity, item.CName)); foreach (var sup in item.customerSuppliers) { Console.WriteLine(string.Format("\t->SCity = {0},SName = {1}",sup.City,sup.Name));}}

数据上的关联2 CCity = CA, CName = CustA, ->SCity = CA,SName = SA CCity = CB, CName = CustB, ->SCity = CB,SName = SB CCity = CC, CName = CustC, ->SCity = CC,SName = SC ->SCity = CC,SName = SD ->SCity = CC,SName = SE CCity = CD, CName = CustD,

数据上的关联3 from c in categories join p in products on new { c.IdCategory, c.Year } equals new { p.IdCategory, p.Year } into productsByCategory

int[] numbers = { 10, 9, 8, 7, 6 }; numbers.Take (3)

int[] numbers = { 10, 9, 8, 7, 6 }; numbers.Skip (3)

int[] numbers = { 10, 9, 8, 7, 6 }; numbers.Reverse()

First,Last int[] numbers = { 10, 9, 8, 7, 6 }; numbers.First(); 运行结果: numbers.Last();

int[] numbers = { 10, 9, 8, 7, 6 }; numbers.Count()

int[] numbers = { 10, 9, 8, 7, 6 }; numbers.Min()

Any int[] numbers = { 10, 9, 8, 7, 6 }; numbers.Any();//如果有元素即为true,否则为false numbers.Any (n => n % 2 == 1);

int[] numbers = { 10, 9, 8, 7, 6 }; numbers.Contains (9);

Contains var orderOfProductOne = new Order {IdOrder = 1, Quantity = 3, IdProduct = 1 , Shipped = false, Month = "January"}; bool result = Orders.Contains(orderOfProductOne); 需要覆盖GetHashCode和Equals方法 改Order类为值类型 public static bool Contains<TSource>( this IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer )

int[] seq1 = { 1, 2, 3 }; int[] seq2 = { 3, 4, 5 }; seq1.Concat (seq2)

int[] seq1 = { 1, 2, 3 }; int[] seq2 = { 3, 4, 5 }; seq1.Union (seq2)

Distinct string[] names = { "Tom","Tom", "Dick", "Harry", "Mary", "Jay" , "Jay"}; IEnumerable<string> query = names.Distinct();

 group by Developer[] developers = new Developer[] { new Developer { Name = "Paolo", Language = "C#" }, new Developer { Name = "Marco", Language = "C#" }, new Developer { Name = "Frank", Language = "VB.NET" }, }; var developersGroupedByLanguage = from d in developers group d by d.Language; foreach (var group in developersGroupedByLanguage) { Console.WriteLine("Language: {0}", group.Key); foreach (var item in group) { Console.WriteLine("\t{0}", item.Name); } }

group by Language: C#           Paolo           Marco   Language: VB.NET           Frank

group by 2 Developer[] developers = new Developer[] { new Developer { Name = "Paolo", Language = "C#", Age = 32 }, new Developer { Name = "Marco", Language = "C#", Age = 37}, new Developer { Name = "Frank", Language = "VB.NET", Age = 48 }, }; var developersGroupedByLanguage = from d in developers group d by new { d.Language, AgeCluster = (d.Age / 10) * 10 }; foreach (var group in developersGroupedByLanguage) { Console.WriteLine("Language: {0}", group.Key); foreach (var item in group) { Console.WriteLine("\t{0}", item.Name); } }

group by 2 Language: { Language = C#, AgeCluster = 30 } Paolo Marco Language: { Language = VB.NET, AgeCluster = 40 }           Frank

group by 3 var developersGroupedByLanguage = from d in developers group d by d.Language into developersGrouped select new { Language = developersGrouped.Key, DevelopersCount = developersGrouped.Count() }; foreach (var group in developersGroupedByLanguage) { Console.WriteLine ("Language {0} contains {1} developers", group.Language, group.DevelopersCount); }

OfType System.Collections.ArrayList fruits = new System.Collections.ArrayList(4); fruits.Add("Mango"); fruits.Add("Orange"); fruits.Add("Apple"); fruits.Add(3.0); fruits.Add("Banana"); IEnumerable<string> query1 = fruits.OfType<string>(); foreach (string fruit in query1) { Console.WriteLine(fruit); } 运行结果: Mango Orange Apple Banana

Cast System.Collections.ArrayList fruits = new System.Collections.ArrayList(); fruits.Add("apple"); fruits.Add("mango"); IEnumerable<string> query = fruits.Cast<string>().Select(fruit => fruit); foreach (string fruit in query) { Console.WriteLine(fruit); } 运行结果: Apple mango

OfType vs Cast OfType: filters the source sequence, yielding only items of type TResult. It is useful in the case of sequences with items of different types. Cast: enumerates the source sequence and tries to yield each item, cast to type TResult. In the case of failure, an InvalidCastException error will be thrown.

Deferred Query Evaluation var numbers = new List<int>(); numbers.Add(1); IEnumerable<int> query = numbers.Select(n => n * 10); numbers.Add(2); foreach (var a in query){ Console.WriteLine(a);}

Deferred Query Evaluation static Boolean DoSomething(Developer dev) { if (dev.Age > 40) throw new ArgumentOutOfRangeException("dev"); return (dev.Language == "C#"); }

Deferred Query Evaluation Developer[] developers = new Developer[] { new Developer { Name = "Frank", Language = "VB.NET", Age = 48 }, … … }; var query = from d in developers let SomethingResult = DoSomething(d) select new { d.Name, SomethingResult }; try { foreach (var item in query) { Console.WriteLine(item); } } catch (ArgumentOutOfRangeException e) { Console.WriteLine(e.Message); }

总结 数据结构上的关联 数据上的关联 OrderBy Take Skip Reverse First,Last Count Min Any Contains Concat Union Distinct group by OfType Cast Deferred Query Evaluation