Linq(语言集成查询)_第1页
Linq(语言集成查询)_第2页
Linq(语言集成查询)_第3页
Linq(语言集成查询)_第4页
Linq(语言集成查询)_第5页
已阅读5页,还剩56页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Linq(语言集成查询语言集成查询)主讲人:大牛主讲人:大牛本章目标本章目标掌握掌握 LINQ 中的基本概念中的基本概念掌握掌握 LINQ 的组成的组成掌握掌握 Linq查询关键字查询关键字from where select groupinto orderby joinlet equals掌握基本查询方法掌握基本查询方法Select() Where() OrderBy() GroupBy()LINQ要解决的问题要解决的问题长期以来,开发社区形成以下格局:长期以来,开发社区形成以下格局:面向对象与数据访问两个领域长期分裂,各自为政面向对象与数据访问两个领域长期分裂,各自为政编程语言中的数据类型与

2、数据库中的数据类型形成两套体编程语言中的数据类型与数据库中的数据类型形成两套体系。例如:系。例如:C# 中字符串用中字符串用 string 表示表示SQL 中字符串用中字符串用 NVarchar/Varchar/Char 表示表示SQL 编码体验落后编码体验落后没有智能感应没有智能感应没有严格意义上的强类型和类型检查没有严格意义上的强类型和类型检查SQL 和和 XML 都有各自的查询语言,而对象没有自己的查都有各自的查询语言,而对象没有自己的查询语言询语言LINQ 将改变这一切!将改变这一切!LINQ 的历史的历史最初由最初由 Anders Hejlsberg 构思,最初构思,最初的研究计划称

3、为的研究计划称为 C2005年年9月月 第一个为第一个为 C# 2.0 开发的开发的技术预览版在当年的技术预览版在当年的 PDC(微软开发者(微软开发者大会)上发布大会)上发布2005年年11月月 更新至社区预览版(更新至社区预览版(C# 2.0)2006年年1月月 第一个为第一个为 VB 8.0 开发开发的技术预览版发布的技术预览版发布2007年年11月月19日日 LINQ作为作为 .NET Framework 3.5 的一部分正式发布的一部分正式发布Anders HejlsbergLINQ是什么是什么LINQ( Language Integrated Query )即语言集成查询)即语言集

4、成查询LINQ 是一组语言特性和是一组语言特性和API,使得你可以使用统一的方,使得你可以使用统一的方式编写各种查询。查询的对象包括式编写各种查询。查询的对象包括XML、对象集合、对象集合、SQL Server 数据库等等。数据库等等。LINQ 主要包含以下三部分:主要包含以下三部分:LINQ to Objects 主要负责对象的查询主要负责对象的查询(如如:集合、数组、字符串等集合、数组、字符串等)LINQ to XML 主要负责主要负责 XML 的查询的查询LINQ to ADO.NET 主要负责数据库的查询主要负责数据库的查询LINQ to SQLLINQ to DataSetLINQ

5、to EntitiesLINQ 的组成的组成 LINQ 初体验初体验在没有在没有LINQ以前,我们这样查询:以前,我们这样查询:int numbers = new int 6, 4, 3, 2, 9, 1, 7, 8, 5 ;List even = new List();foreach (int number in numbers) if (number % 2 = 0) even.Add(number); even.Sort();even.Reverse();从从 numbers 数组中提取数组中提取偶数并降序排列偶数并降序排列LINQ 初体验初体验今天,我们有了今天,我们有了LINQ! 我

6、们这样查询:我们这样查询:int numbers = new int 6, 4, 3, 2, 9, 1, 7, 8, 5 ;var even = numbers .Where(p = p % 2 = 0) .Select(p = p) .OrderByDescending(p = p);从从 numbers 数组中提取数组中提取偶数并降序排列偶数并降序排列演示示例:演示示例:Hello, LINQfrom 子句子句 查询表达式必须以查询表达式必须以 from 子句开头。另外,查询表达式还子句开头。另外,查询表达式还可以包含子查询,子查询也是以可以包含子查询,子查询也是以 from 子句开头。子

7、句开头。from 子句指定以下内容子句指定以下内容 将对其运行查询或子查询的数据源。将对其运行查询或子查询的数据源。 一个本地范围变量,表示源序列中的每个元素。一个本地范围变量,表示源序列中的每个元素。 int numbers = 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 ; var lowNums = from num in numbers where num 5 select num; foreach (int i in lowNums) Console.Write(i + ); 输出结果输出结果: 4 1 3 2 0 范围变量范围变量where 子句子句 where 子句

8、用在查询表达式中,用于指定将在查询表达式子句用在查询表达式中,用于指定将在查询表达式中返回数据源中的哪些元素。一个查询表达式可以包含多中返回数据源中的哪些元素。一个查询表达式可以包含多个个 where 子句,一个子句可以包含多个谓词子表达式。子句,一个子句可以包含多个谓词子表达式。 int numbers = 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 ; var queryLowNums = from num in numbers where num 5 select num; foreach (var s in queryLowNums) Console.Write(s.To

9、String() + ); 输出结果输出结果: 4 1 3 2 0 谓词谓词(布尔条件布尔条件 )select 子句子句 在查询表达式中,在查询表达式中,select 子句可以指定将在执行查询时产子句可以指定将在执行查询时产生的值的类型。该子句的结果将基于前面所有子句的计算生的值的类型。该子句的结果将基于前面所有子句的计算结果以及结果以及 select 子句本身中的所有表达式。查询表达式子句本身中的所有表达式。查询表达式必须以必须以 select 子句或子句或 group 子句结束。子句结束。List Scores = new List() 97, 92, 81, 60 ; IEnumerab

10、le queryHighScores = from score in Scores where score 80 select score; foreach (int i in queryHighScores) Console.Write(i + ); 输出结果输出结果: 97 92 81group 子句子句 group 子句返回一个子句返回一个 IGrouping(Of ) 对象序列,这些对象包含零个或更多个与对象序列,这些对象包含零个或更多个与该组的键值匹配的项。该组的键值匹配的项。 var studentQuery2 =from student in studentsgroup stud

11、ent by student.Last0into g orderby g.Key select g; in in 上下文关键字可在下面两种上下文中使用:上下文关键字可在下面两种上下文中使用: foreach 语句语句 查询表达式中的查询表达式中的 join 子句子句 by by 上下文关键字用在查询表达式的上下文关键字用在查询表达式的 group 子句中,用于子句中,用于指定如何对返回的项进行分组。指定如何对返回的项进行分组。var query = from student in students group student by student.LastName0; equals equal

12、s 上下文关键字用在查询表达式的上下文关键字用在查询表达式的 join 子句中,用子句中,用于比较两个序列的元素。于比较两个序列的元素。 var innerJoinQuery = from category in categories join prod in products on category.ID equals prod.CategoryID select new ProductName = prod.Name, Category = category.Name ; on on 上下文关键字在查询表达式的上下文关键字在查询表达式的 join 子句中用于指定联子句中用于指定联接条件。接

13、条件。 var innerJoinQuery = from category in categories join prod in products on category.ID equals prod.CategoryID select new ProductName = prod.Name, Category = category.Name ; descending descending 上下文关键字用在查询表达式的上下文关键字用在查询表达式的 orderby 子子句中,用于指定从最大到最小的排序顺序。句中,用于指定从最大到最小的排序顺序。 ascending ascending 上下文关

14、键字用在查询表达式的上下文关键字用在查询表达式的 orderby 子子句中,用于指定从最小到最大的排序顺序。因为句中,用于指定从最小到最大的排序顺序。因为 ascending 是默认排序顺序是默认排序顺序,所以您无须指定它。,所以您无须指定它。 let 子句子句 基本查询操作符基本查询操作符-获取数据获取数据public static IEnumerable Select ( this IEnumerable source, Func selector ) Select()说明说明Select 方法本身是一个泛型扩展方法方法本身是一个泛型扩展方法它作用于它作用于IEnumerable类型类型它

15、只接受一个它只接受一个 Func 类型参数类型参数Func 是一个泛型委托,位于是一个泛型委托,位于System名字空间下,名字空间下,System.Core.dll中中在这里在这里 selector 是一个提取器是一个提取器Select() 例子例子var q1 = foxRiver8.Select(name = name.ToLower();foreach (var item in q1) Console.WriteLine(item);以以 Lambda 表达式形式出现的表达式形式出现的Func委托实例委托实例演示示例:演示示例:Select方法示例方法示例基本查询操作符基本查询操作符-

16、过滤数据过滤数据public static IEnumerable Where( this IEnumerable source, Func predicate ) Where()说明说明Where方法也是一个泛型扩展方法方法也是一个泛型扩展方法它和它和 Select() 一样作用于一样作用于IEnumerable类型类型它只接受一个它只接受一个 Func 泛型委托参数泛型委托参数在这里在这里 predicate 是一个判断条件是一个判断条件Where() 例子例子var q2 = foxRiver8 .Where( name = name.StartsWith(T) .Select(name

17、 = name.ToLower();foreach (var item in q2) Console.WriteLine(item);以以 Lambda 表达式形式出表达式形式出现的判断条件,注意返回现的判断条件,注意返回值要求为值要求为 bool 类型类型演示示例:演示示例:Where方法示例方法示例基本查询操作符基本查询操作符-排序数据排序数据public static IOrderedEnumerable OrderBy( this IEnumerable source, Func keySelector ) OrderBy()说明说明OrderBy方法也是一个泛型扩展方法方法也是一个泛

18、型扩展方法它和它和 Select() 一样作用于一样作用于IEnumerable类型类型它只接受一个它只接受一个 Func 类型参数类型参数在这里在这里 keySelector 指定要排序的字段指定要排序的字段如果想降序排列可以使用如果想降序排列可以使用OrderByDescending方法方法OrderBy() 例子例子var q3 = foxRiver8 .Where(name = name.Length 5) .Select(name = name.ToLower() .OrderBy(name = name.Substring(1,1) foreach (var item in q3)

19、 Console.WriteLine(item);排序字段,这里指定按照姓名的排序字段,这里指定按照姓名的第二个字母升序排列第二个字母升序排列演示示例:演示示例:OrderBy方法示例方法示例基本查询操作符基本查询操作符-分组数据分组数据public static IEnumerableIGrouping GroupBy( this IEnumerable source, Func keySelector ) GroupBy()说明说明GroupBy方法和方法和OrderBy方法非常类似,它也是一个方法非常类似,它也是一个泛型扩展方法泛型扩展方法它和它和 OrderBy() 一样作用于一样作用

20、于IEnumerable类型类型它只接受一个它只接受一个 Func 类型参数类型参数在这里在这里 keySelector 指定要分组的字段指定要分组的字段请注意这个返回值与前面请注意这个返回值与前面方法的返回值的区别方法的返回值的区别GroupBy() 例子例子var q4 = foxRiver8 .Where(name = name.Length 5) .Select(name = name.ToLower() .GroupBy(name = name.Substring(0, 1);foreach (var group in q4) Console.WriteLine(group.Key)

21、; Console.WriteLine(-); foreach (var item in group) Console.WriteLine(item); 外层循环得到分组外层循环得到分组演示示例:演示示例:GroupBy方法示例方法示例内层循环得到分组中的项内层循环得到分组中的项查询执行的时机查询执行的时机int numbers = new int 6, 4, 3, 2, 9, 1, 7, 8, 5 ;var even = numbers .Where(p = p % 2 = 0) .Select(p = Console.WriteLine(Hi! + p.ToString(); return

22、 p; );演示示例:演示示例:查询的时机查询的时机请判断以下代码输出结果是什么?请判断以下代码输出结果是什么?查询执行的时机查询执行的时机var even = numbers .Where(p = p % 2 = 0) .Select(p = Console.WriteLine(Hi! + p.ToString(); return p; );int numbers = new int 6, 4, 3, 2, 9, 1, 7, 8, 5 ;定义查询定义查询获取数据源获取数据源执行查询执行查询foreach (var item in even) 从前面的试验中,我们发现一次查询实际经过以下三步从

23、前面的试验中,我们发现一次查询实际经过以下三步123查询执行的时机小结查询执行的时机小结查询分为以下三步:获取数据源、定义查询、执行查询;查询分为以下三步:获取数据源、定义查询、执行查询;定义查询后,查询直到需要枚举结果时才被真正执行,这定义查询后,查询直到需要枚举结果时才被真正执行,这种方式称为种方式称为“延迟执行延迟执行(deferred execution)”;当查询方法返回单一值时,查询立即执行;当查询方法返回单一值时,查询立即执行;因此,可以通过以下技巧在定义查询时就强制执行查询;因此,可以通过以下技巧在定义查询时就强制执行查询;var even = numbers .Where(p

24、 = p % 2 = 0) .Select(p = Console.WriteLine(Hi! + p.ToString(); return p; ).Count();LINQ查询的两种方式查询的两种方式事实上,事实上,LINQ查询存在以下两种形式查询存在以下两种形式Method Syntax, 查询方法方式查询方法方式主要利用主要利用 System.Linq.Enumerable 类中定义的扩展方法和类中定义的扩展方法和 Lambda 表达式方式进行查询表达式方式进行查询上一章的例子都是以这种方式查询上一章的例子都是以这种方式查询Query Syntax, 查询语句方式查询语句方式一种更接近

25、一种更接近 SQL 语法的查询方式语法的查询方式可读性更好可读性更好查询语句查询语句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);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 descendi

26、ng select number;查询方法查询方法查询语句查询语句演示示例:演示示例:查询语句与查询方法对比示例查询语句与查询方法对比示例两者的执行效果完全一样两者的执行效果完全一样更复杂的查询语句示例更复杂的查询语句示例List foxRiver8 = GetFoxRiver8();var q = from p in foxRiver8 where p.Age p.Age = 30).Count();int count = (from p in foxRiver8 where p.Age p.Age).Max();int maxAge = (from p in foxRiver8select

27、 p.Age).Max();纯粹查询方法模式纯粹查询方法模式混合模式混合模式演示示例:演示示例:Max 方法示例方法示例Max 返回集合中的最大值返回集合中的最大值Min 示例示例int maxAge = foxRiver8 .Select(p = p.Age).Min();int maxAge = (from p in foxRiver8select p.Age).Min();纯粹查询方法模式纯粹查询方法模式混合模式混合模式演示示例:演示示例:Min 方法示例方法示例Min 返回集合中的最小值返回集合中的最小值Average 示例示例double averageAge = foxRiver8

28、.Select(p = p.Age).Average();double averageAge = (from p in foxRiver8select p.Age).Average();纯粹查询方法模式纯粹查询方法模式混合模式混合模式演示示例:演示示例:Average 方法示例方法示例Average 返回集合的平均值返回集合的平均值Sum 示例示例int sumAge = foxRiver8.Select(p = p.Age).Sum();Int sumAge = (from p in foxRiver8select p.Age).Sum();纯粹查询方法模式纯粹查询方法模式混合模式混合模式演

29、示示例:演示示例:Sum 方法示例方法示例Sum 返回集合的总和返回集合的总和排序类查询方法排序类查询方法排序类查询方法排序类查询方法ThenByThenBy 示例示例var q = from p in foxRiver8 orderby p.FirstName, p.LasName, p.Age select p;var q = foxRiver8.OrderBy(p = p.FirstName) .ThenBy(p = p.LasName) .ThenBy(p = p.Age);查询语句查询语句查询方法查询方法演示示例:演示示例:ThenBy 方法示例方法示例ThenBy 提供复合排序条件

30、提供复合排序条件分区类查询方法分区类查询方法分区类查询方法分区类查询方法Take/TakeWhileSkip/SkipWhileTake/Skip 示例示例int numbers = 1, 2, 3, 4, 5, 6, 7, 8, 9 ;var q = numbers.Skip(1).Take(3);foreach (var item in q) Console.WriteLine(item);演示示例:演示示例:Skip/Take 方法示例方法示例Take 提取指定数量的项提取指定数量的项 Skip 跳过指定数量的项并获取剩余的项跳过指定数量的项并获取剩余的项跳过前跳过前1条记录,连条记录,

31、连续提取续提取3条记录,得条记录,得到到 2 3 4TakeWhile/SkipWhile 示例示例演示示例:演示示例:SkipWhile/TakeWhile 方法示例方法示例TakeWhile 根据指定条件提取项根据指定条件提取项 SkipWhile 根据指定条件跳过项根据指定条件跳过项int numbers = 1, 2, 3, 4, 5, 6, 7, 8, 9 ;var q = numbers.SkipWhile(i = i % 3 != 0) .TakeWhile(i = i % 2 != 0); foreach (var item in q) Console.WriteLine(it

32、em);分区类查询方法小结分区类查询方法小结请判断以下代码输出结果是什么?请判断以下代码输出结果是什么?int numbers = 1, 2, 3, 4, 5, 6, 7, 8, 9 ;var q = numbers.Skip(1).Take(3).Skip(1).Take(2);foreach (var item in q) Console.WriteLine(item);输出输出: 3 4集合类查询方法集合类查询方法集合类查询方法集合类查询方法DistinctDistinct 示例示例演示示例:演示示例:Distinct 方法示例方法示例Distinct 去掉集合中的重复项去掉集合中的重复

33、项 int factorsOf300 = 2, 2, 3, 5, 5 ;var uniqueFactors = factorsOf300.Distinct();输出输出: 2 3 5生成类查询方法生成类查询方法生成类查询方法生成类查询方法RangeRepeatRange 示例示例演示示例:演示示例:Range 方法示例方法示例Range 生成一个整数序列生成一个整数序列 var numbers =Enumerable.Range(1, 10);foreach (var item in numbers) Console.WriteLine(item);Repeat 示例示例演示示例:演示示例:R

34、epeat 方法示例方法示例Repeat 生成一个重复项的序列生成一个重复项的序列 var numbers =Enumerable.Repeat(“Beijing 2008”, 10);foreach (var item in numbers) Console.WriteLine(item);生成类查询方法小结生成类查询方法小结使用生成类查询方法时,需要注意以下几点:使用生成类查询方法时,需要注意以下几点:和其他几类方法不同,和其他几类方法不同,Range/Repeat 不是扩展方法,而不是扩展方法,而是普通的静态方法是普通的静态方法Range 只能产生整数序列只能产生整数序列Repeat 可

35、以产生泛型序列可以产生泛型序列所有的查询方法都存放在所有的查询方法都存放在 System.Linq.Enumerable 静静态类中态类中LINQ to SQL 示例示例下面我们利用已经学习的下面我们利用已经学习的 LINQ 知识,做一个示例知识,做一个示例显示显示“第三波书店第三波书店”中所有书籍类型中所有书籍类型根据用户选择的书籍类型显示书籍列表根据用户选择的书籍类型显示书籍列表提供分页功能:提供分页功能:首页首页上一页上一页下一页下一页末页末页页码选择页码选择设计界面设计界面关键步骤关键步骤新建新建 “ASP.NET Web Site” 项目项目在在 “Solution Explorer

36、” 中依次选择中依次选择 “Add New Item” - “Web Form”为网页命名为为网页命名为 ListBooksByCategory.aspx设计简单的用户界面,设计好后的界面如图所示设计简单的用户界面,设计好后的界面如图所示配置数据源配置数据源关键步骤关键步骤在在 “Database Explorer” 中选择中选择 “Add Connection”,并指定,并指定 MyBookShop 数据库数据库在在 “Solution Explorer” 中依次选择中依次选择 “Add New Item” - “LINQ to SQL Classes”为为dbml文件命名为文件命名为 MyBookShop.dbml展开数据源视图,把展开数据源视图,把 MyBookShop 数据库中的表数据库中的表 Books, Categories, Publishers 拖到拖到 LINQ to SQL 的设计器中的设计器中最终效果如图最终效果如图编写代码编写代码在在 Page_Load 中编写代码进行初始化中编写代码进行初始化private const int PAGE_SIZE = 20;MyBookShopDataContext db;protected void Page_Load(object sender, EventArgs e) db = new MyBookShopD

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论