• LINQ简记(3):子句


    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(" 大于20的整数有: ");  
    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(" 以“T”开头并且长度在3以上的字符串有: ");  
    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.   
    14. Debug.Write(" 查询结果变量的类型:" + res3.GetType().Name + " ");  
    15. Debug.Write(" 分别输出各分组的信息: ");  
    16. foreach (var g in res3)  
    17. {  
    18.     Debug.WriteLine("数据类型:" + g.GetType().Name);  
    19. }  


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

    1.  查询结果变量的类型:GroupedEnumerable`3  
    2.   
    3. 分别输出各分组的信息:  
    4. 数据类型:Grouping  
    5. 数据类型:Grouping  
    6. 数据类型: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  
  • 相关阅读:
    HDU 2121 Ice_cream’s world II 不定根最小树形图
    POJ 3164 Command Network 最小树形图
    POJ 3723 Conscription 最小生成树
    UVA 1175 Ladies' Choice 稳定婚姻问题
    BZOJ 2753 [SCOI2012] 滑雪和时间胶囊 最小生成树
    BZOJ 1854: [Scoi2010]游戏 无向图判环
    HDU 3974 Assign the task 暴力/线段树
    Codeforces Round #302 (Div. 2) D. Destroying Roads 最短路
    uoj 67 新年的毒瘤 割点
    蓝桥
  • 原文地址:https://www.cnblogs.com/xieweikai/p/6832834.html
Copyright © 2020-2023  润新知