代码改变世界

Linq学习笔记(一)——Linq To Objects 预览

2009-11-14 20:08  Henry Cui  阅读(580)  评论(1编辑  收藏  举报

Linq是C#3.0里面的东西,现在C#4.0都快出来了,有点落伍了,还是务实下基础。

必备知识:

C#3.0新特性的基础(1,2,3

 

基础数据

首先我们看一个基础数据(项目-模块-功能点)的图:

image

然后在BaseDate中Projects的数据(代码1.1):

  1. public static Projects[] ProjectList =
  2.         {
  3.             new Projects{ProjectsID="CAMS_NT",ProjectsName="信息系统-NT",CreateDate=new DateTime(2008,1,3)},
  4.             new Projects{ProjectsID="CAMS_WX",ProjectsName="信息系统-WX",CreateDate=new DateTime(2008,5,3)},
  5.             new Projects{ProjectsID="WMS",ProjectsName="仓储系统",CreateDate = new DateTime(2009,5,3)}
  6.         };

预览Demo

现在我们需要从数组中找出ProjectsID以CAMS开头的所有的项目的项目名称。在C#2.0之前我们莫非于这样(代码1.2):

  1. List<string> projectnames = new List<string>();
  2. foreach (Projects project in BaseDate.BaseData.ProjectList)
  3. {
  4.     if (project.ProjectsID.StartsWith("CAMS"))
  5.         projectnames.Add(project.ProjectsName);
  6. }
  7. foreach (string proname in projectnames)
  8. {
  9.     Console.WriteLine(proname);
  10. }

 

我们可以通过C#3.0中提供的扩展方法进行更为方便实现(代码1.3):

  1. var projectnames = BaseDate.BaseData.ProjectList.Where(project => project.ProjectsID.StartsWith("CAMS"))
  2.     .Select(project => project.ProjectsName);
  3. foreach (var proname in projectnames)
  4. {
  5.     Console.WriteLine(proname);
  6. }

 

而我们还可以通过linq更为简洁的实现(代码1.4):

  1. var projectnames = from project in BaseData.ProjectList
  2.                    where project.ProjectsID.StartsWith("CAMS")
  3.                    select project.ProjectsName;
  4. foreach (var proname in projectnames)
  5. {
  6.     Console.WriteLine(proname);
  7. }

在代码1.2中实现就不必多说,在代码1.3中通过了扩展方法where以及select实现了过滤以及查询功能,而在代码1.4中我们看到了一种类似于sql语句的查询,这就是Linq查询表达式的语法,可以看到是多么的方便。

 

查询表达式的编写

  1. from [type] id in source
  2. [join [type] IDictionary in source on expr equals expr [into id]]
  3. {from[type] id in source |let id = expr|where condition}
  4. [orderby ordering,odering,...]
  5. select expr | group expr by key
  6. [into id query]

 

首先查询表达式从from字句开始;

最开始的from字句口可以跟多个from、let、where、join、orderby 字句;

最后以select或则group字句结束。

每个from字句都能引入一个新的变量,用来依次访问某个序列中的每个元素;每个let都会引入新的变量,用来表示前面计算出来的值;每个where字句都会过滤一些元素,每个join字句都会指定某个字段跟另外序列字段进行关联;orderby进行排序;group、select决定集合的结构。

其实在我们用linq查询表达式编写出来的代码最后都会装变成调用扩展方法的形式,所以说代码1.4跟代码1.3的本质是一样的。

 

查询表达式的限制

相对于扩展方法的方式,有些方法是在表达式语法中无法实现的。如:Take、Distinct。所以我们需要在扩展方法形式以及查询表达式形式的两种选择时,要按照自己的需要来。

同时还需要注意的是,所要的查询只可用于可被枚举的集合对象上:

1.数组

2.泛型列表

3.泛型字典

要注意的是Linq无法支持DataSet、ArrayList等非泛型集合。