LINQ查询表达式的子句如select,where,from等都是比较简单的子句,相信各位多练习练习,再结合MSDN的例子,基本上是可以理解的,因此,本文只挑几个有代表性的,以及有些难理解的子句来简述一下。
 
一、where子句。
在SQL中,筛选语句常用的表示方式如“select * from Users where uName = 'DMIN'”,这个SQL语句就带有WHERE子句,其实,在LINQ中也类似,只不过放的位置不一样。请看下面的例子。
 
  1. int[] Source1 = new int[] { 10, 50, 22, 38, 91, 17 };
  2. // 筛选出大于20的数字
  3. var res =
  4. from n in Source1
  5. where n > 20
  6. select n;
  7. Debug.Write("\n\n大于20的整数有:\n");
  8. foreach (int x in res)
  9. {
  10. Debug.Write("  " + x);
  11. }

输出的结果为:

  1. 大于20的整数有:
  2. 50  22  38  91

复合条件的写法与if等判断语句一致,LINQ遵循C#语法,再看看下面一个例子,从字符串数组中选出以T开头并且长度大于等于3的。

  1. string[] Source2 = new string[]{
  2. "Time", "Apple", "Noooooode", "DogDoorDoc", "TikkyOde"
  3. };
  4. var res2 =
  5. from s in Source2
  6. where s.StartsWith("T") && s.Length >= 3
  7. select s;
  8. Debug.Write("\n\n以“T”开头并且长度在3以上的字符串有:\n");
  9. foreach (string str in res2)
  10. {
  11. Debug.Write("  " + str);
  12. }

输出结果如下:

  1. 以“T”开头并且长度在3以上的字符串有:
  2. Time  TikkyOde

二、group子句。

这是一个有点儿难度的子句,很多朋友可能搞不清楚它查询后返回的是什么。这样,我们还是用一个例子来说明吧。

首先,声明一个类,包含两个字段:学生姓名和成绩。

  1. public class Student
  2. {
  3. public string Name { get; set; }
  4. public int Score { get; set; }
  5. }

接着,我们把学生的名字以首字母进行分组。

  1. Student[] Source3 = new Student[]{
  2. new Student{Name="ZhangFeng", Score = 60},
  3. new Student{ Name = "LiuXiaoShan", Score = 75 },
  4. new Student{ Name = "LiangWuTai", Score = 80 },
  5. new Student{ Name = "ZhongNing", Score = 65 },
  6. new Student{ Name = "FuNan", Score = 71 },
  7. new Student{ Name = "LanAo", Score = 79 },
  8. new Student{ Name = "FangTianHao", Score = 88 }
  9. };
  10. var res3 =
  11. from st in Source3
  12. group st by st.Name[0];
  13. Debug.Write("\n\n查询结果变量的类型:" + res3.GetType().Name + "\n");
  14. Debug.Write("\n分别输出各分组的信息:\n");
  15. foreach (var g in res3)
  16. {
  17. Debug.WriteLine("数据类型:" + g.GetType().Name);
  18. }

调试运行,然后注意查看“输出窗口”中的内容。

  1. 查询结果变量的类型:GroupedEnumerable`3
  2. 分别输出各分组的信息:
  3. 数据类型:Grouping
  4. 数据类型:Grouping
  5. 数据类型:Grouping

因此,我们可以得到这样的结果:

1、分组查询返回一个GroupedEnumerable;

2、每个GroupedEnumerable中包含N个Grouping。

我们发现这些类在对象浏览器中找不到,GroupedEnumerable是内部类,但Grouping通过反射也没找着,那它们的结构到底如何?

现在,我们通过断点调试,进一步了解它们。

从截图中我们看到,IGrouping<TKey,TElement>有一个Key属性,其实它就是存储我们用来进行分组的键,怎么理解呢?

回到上面的例子,我们以什么作为分组的依据?对,姓名字段的第一个个字母,其实是Char类型,因此,比如上面的,“Z”就是一个组的键,在这个组里面,都是以Z开头的对象的集合。

我们可以下一个不成文的结论:分组结果中的所谓Key就是我们用于分组所依据的字段或具体的值。

在实现IGrouping<TKey,TElement>的类中,显然会实现GetEnumerator方法,也就是说我们可以把它foreach出来,上图中看到,每个元素(TElement)说白了就是已经被分组的对象,上例中即为Student对象。

而每个组中其实包含Lookup<TKey,TElement>类。

呵呵,有些混乱了,我们可以这样总结:

执行了LINQ分组查询后,得到的所有分组的集合A,而A中的每个成员就是一个组G1、G2……而G1中就是被分到该组的对象O1、O2……可能用一个图来表示会直观一点。

现在,我们把上面的代码改一下。

  1. foreach (var g in res3)
  2. {
  3. Debug.WriteLine(g.Key);
  4. foreach (var item in g)
  5. {
  6. Debug.WriteLine("姓名:" + item.Name);
  7. Debug.WriteLine("成绩:" + item.Score);
  8. }
  9. }

输出结果如下:

  1. Z
  2. 姓名:ZhangFeng
  3. 成绩:60
  4. 姓名:ZhongNing
  5. 成绩:65
  6. L
  7. 姓名:LiuXiaoShan
  8. 成绩:75
  9. 姓名:LiangWuTai
  10. 成绩:80
  11. 姓名:LanAo
  12. 成绩:79
  13. F
  14. 姓名:FuNan
  15. 成绩:71
  16. 姓名:FangTianHao
  17. 成绩:88

LINQ简记(3):子句的更多相关文章

  1. Linq之select子句

    在Linq中select子句用来指定查询结果的类型和表现形式.Linq查询要么以select子句结尾,要么以group子句结尾. List<UserBaseInfo> users = ne ...

  2. linq group by子句

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  3. linq之join子句

    前面我们总结Linq查询子句总共有8个,join子句是我们讲解的最后一个子句.join子句也是相对比较复杂的,所以最后来讲.join子句可以处理两个数据源之间的联系,当然这两个数据源之间必须存在相关联 ...

  4. linq之let子句

    在Linq查询中Let子句可以创建一个新的范围变量,并使用该变量保存表达式的结果. 看下面的例子: private void LetQuery() { List<UserBaseInfo> ...

  5. linq之into子句

    在Linq表达式中,into子句可以创建一个临时标识符,使用该标识符可以存储group.join或select子句的结果. 下面实例中我们用GroupOtherQuery方法来演示group子句对结果 ...

  6. linq之orderby子句

    在Linq查询中,orderby 子句可以对查询结果集进行排序,可以升序也可以降序,排序关键字可以是多个.默认排序方式为升序. 下面的实例代码OrderQuery()中演示了orderby子句对查询的 ...

  7. Linq之group子句

    在Linq查询语句中,group子句主要作用是对查询的结果集进行分组.并返回元素类型为IGrouping<TKey,TElement>的对象序列. 下面我们在代码实例中创建一个GroupQ ...

  8. linq之where子句

    在Linq中,where子句主要是来指定筛选元素的逻辑条件.linq查询中where子句不是必须的,可以不包括where子句,也可以包含多个where子句,where子句中可以包含一个或多个bool类 ...

  9. Linq专题之Linq查询from子句

    Linq查询表达式包含8个常用的子句:from.where.select.join.into.orderby.group.let.我们来看看详细的说明.      from:      指定查询操作的 ...

随机推荐

  1. ListView布局之View复用原理举例

    1.简单介绍: ListView是android开发中经常使用的控件,系统自带的那些样式,我就不列举了. 今天主要看一下.一个模仿系统历史通话记录的ListView. 效果例如以下: 上面ListVi ...

  2. 【网络流】 HDU 3468 Treasure Hunting

    题意: A-Z&&a-z 表示 集结点 从A点出发经过 最短步数 走到下一个集结点(A的下一个集结点为B ,Z的下一个集结点为a) 的路上遇到金子(*)则能够捡走(一个点仅仅能捡一次) ...

  3. 动态DNS——本质上是IP变化,将任意变换的IP地址绑定给一个固定的二级域名。不管这个线路的IP地址怎样变化,因特网用户还是可以使用这个固定的域名 这样看的话,p2p可以用哇

    动态域名是因应网络远程访问的需要而产生的一项应用技术.因为没有固定IP,只能运用二级域名来应对经常变化的IP,动态域名的由来因此而产生. 它当前主要应用在:路由器.网络摄像机.带网络监控的硬盘录像机. ...

  4. 如何根据configure.ac和Makefile.am为开源代码产生当前平台的Makefile

    1 2 3 4 5 6 7 8 9 //根据configure.in和Makefile.am生成makefile的步骤,基于UBUNTU 12.04 1.autoscan (可选) 2.aclocal ...

  5. PCB genesis连孔加除毛刺孔(圆孔与槽孔)实现方法(二)

    一.为什么 连孔加除毛刺孔 原因是 PCB板材中含有玻璃纤维, 毛刺产生位置在于2个孔相交位置,由于此处钻刀受力不均导致纤维切削不断形成毛刺 ,为了解决这个问题:在钻完2个连孔后,在相交处再钻一个孔, ...

  6. Linux基本命令 文件管理 上部

    第1章 Linux入门相关 目录基本知识 Linux一切从根开始 倒挂的树形结构 对路径与相对路径 绝对路径: 从根开始的路径 比如:/oldboy  /data 相对路径: 没有从根开始的路径 比如 ...

  7. bzoj1121[POI2008]激光发射器SZK(结论)

    1121: [POI2008]激光发射器SZK Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 916  Solved: 759[Submit][Sta ...

  8. centos6.6安装redis

    .安装仓库 yum install epel-release -y2.安装redis yum install redis -y3.程序文件说明 安装完毕后有以下几个文件位于/usr/bin目录: re ...

  9. Unity学习-预制(四)

    预制即克隆 比如要模拟一个下雨的场景,天下掉下来一颗一颗的雨滴.如果此时,我们给每一个雨滴创建一个对象的话,那会很浪费资源,而且也没必要,因为所有的雨滴是相同的.这个时候就使用到了预制,一种可以被重复 ...

  10. 01--TCP状态转换

    参考大牛文章: http://www.cnblogs.com/qlee/archive/2011/07/12/2104089.html