• LINQ查询表达式(3)


    对查询结果进行分组

      分组是 LINQ 最强大的功能之一。

      下面的示例演示如何以各种方式对数据进行分组:

    • 按照单个属性。
    • 按照字符串属性的首字母。
    • 按照计算出的数值范围。
    • 按照布尔谓词或其他表达式。
    • 按照复合键。

      此外,最后两个查询将它们的结果投影到一个新的匿名类型中,该类型仅包含学生的名字和姓氏。

    //单个属性作为组键对源元素进行分组
     var queryLastNames =
                    from student in students
                    group student by student.LastName into newGroup
                    orderby newGroup.Key
                    select newGroup;
    
    通过使用除对象属性以外的某个项作为组键对源元素进行分组, 在此示例中,键是学生姓氏的第一个字母
      var queryFirstLetters =
                    from student in students
                    group student by student.LastName[0];
    
    /*
    通过使用某个数值范围作为组键对源元素进行分组。 然后,查询将结果投影到一个匿名类型中,该类型仅包含学生的名字和姓氏以及该学生所属的百分点范围。 使用匿名类型的原因是没有必要使用完整的 Student 对象来显示结果。*/
    Helper method, used in GroupByRange.
            protected static int GetPercentile(Student s)
            {
                double avg = s.ExamScores.Average();
                return avg > 0 ? (int)avg / 10 : 0;
            }
    
      var queryNumericRange =
                    from student in students
                    let percentile = GetPercentile(student)
                    group new { student.FirstName, student.LastName } by percentile into percentGroup
                    orderby percentGroup.Key
                    select percentGroup;
    
    //通过使用布尔比较表达式对源元素进行分组
      var queryGroupByAverages = from student in students
                                           group new { student.FirstName, student.LastName }
                                                by student.ExamScores.Average() > 75 into studentGroup
                                           select studentGroup;
    
    /*
    下面的示例演示如何使用匿名类型来封装包含多个值的键。 在此示例中,第一个键值是学生姓氏的第一个字母。 第二个键值是一个布尔值,它指定该学生在第一次考试中的得分是否超过了 85。 可以按照该键中的任何属性对多组值进行排序。*/
     var queryHighScoreGroups =
                    from student in students
                    group student by new { FirstLetter = student.LastName[0], 
                        Score = student.ExamScores[0] > 85 } into studentGroup
                    orderby studentGroup.Key.FirstLetter
                    select studentGroup;

     创建嵌套分组

          public void QueryNestedGroups()
            {
                var queryNestedGroups =
                    from student in students
                    group student by student.Year into newGroup1
                    from newGroup2 in
                        (from student in newGroup1
                         group student by student.LastName)
                    group newGroup2 by newGroup1.Key;
    
                // Three nested foreach loops are required to iterate 
                // over all elements of a grouped group. Hover the mouse 
                // cursor over the iteration variables to see their actual type.
                foreach (var outerGroup in queryNestedGroups)
                {
                    Console.WriteLine("DataClass.Student Level = {0}", outerGroup.Key);
                    foreach (var innerGroup in outerGroup)
                    {
                        Console.WriteLine("	Names that begin with: {0}", innerGroup.Key);
                        foreach (var innerGroupElement in innerGroup)
                        {
                            Console.WriteLine("		{0} {1}", innerGroupElement.LastName, innerGroupElement.FirstName);
                        }
                    }
                }
            }

       分组数据类型IGrouping接口:

    namespace System.Linq
    { 
        public interface IGrouping<out TKey, out TElement> : IEnumerable<TElement>, IEnumerable
        {
            TKey Key { get; }
        }
    
      public interface ILookup<TKey, TElement> : IEnumerable<IGrouping<TKey, TElement>>, IEnumerable
        {
            IEnumerable<TElement> this[TKey key] { get; }
            int Count { get; }
            bool Contains(TKey key);
        }
    }

     对分组操作执行子查询

      创建一个查询,以便将源数据排序到不同的组中,然后分别对每个组执行子查询。

      每个示例中的基本技术都是使用一个名为 studentGroup 的“延续”对源元素进行分组,然后生成一个针对 studentGroup的新的子查询。 此子查询是针对外部查询所创建的每个新组运行的。

      请注意,在此特定示例中,最终的输出不是组,而是匿名类型的平面序列,代码如下:

        public void QueryMax()
            {
                var queryGroupMax =
                    from student in students
                    group student by student.Year into studentGroup
                    select new
                    {
                        Level = studentGroup.Key,
                        HighestScore =
                        (from student2 in studentGroup
                         select student2.ExamScores.Average()).Max()
                    };
    
                int count = queryGroupMax.Count();
                Console.WriteLine("Number of groups = {0}", count);
    
                foreach (var item in queryGroupMax)
                {
                    Console.WriteLine("  {0} Highest Score={1}", item.Level, item.HighestScore);
                }
            }

    参考

      [1]MSDN,对查询结果进行分组

  • 相关阅读:
    前端页面适配的rem换算
    Win10远程桌面 出现 身份验证错误,要求的函数不受支持,这可能是由于CredSSP加密Oracle修正 解决方法
    ES5, ES6, ES2016, ES.Next: What's going on with JavaScript versioning?
    国内的Android SDK镜像
    虚拟串口VSPD破解版 亲测win10 64可用
    Mybatis : "less than" issue in Select annotations
    如何在MyBatis中优雅的使用枚举
    Adding a custom jar as a maven dependency
    Error: Invalid or corrupt jarfile
    使用Json让Java和C#沟通的方法
  • 原文地址:https://www.cnblogs.com/ybtools/p/6526733.html
Copyright © 2020-2023  润新知