LINQ 笔记 - 语法与关键字
2008-02-27 21:27 Animax! 阅读(658) 评论(3) 收藏 举报
查询操作的三个部分:
所有 LINQ 查询操作都由以下三个不同的操作组成:
1.获取数据源。
2.创建查询。
3.执行查询。
 static void Main()
    static void Main()
 {
    {
 // 1. 数据源
        // 1. 数据源
 int[] numbers = new int[7] { 0, 1, 2, 3, 4, 5, 6 };
        int[] numbers = new int[7] { 0, 1, 2, 3, 4, 5, 6 };

 // 2. 创建查询
        // 2. 创建查询
 // 这里numQuery变量的类型为IEnumerable<int>
        // 这里numQuery变量的类型为IEnumerable<int>
 var numQuery =
        var numQuery =
 from num in numbers
            from num in numbers
 where (num % 2) == 0
            where (num % 2) == 0
 select num;
            select num;

 // 3. 执行查询
        // 3. 执行查询
 foreach (int num in numQuery)
        foreach (int num in numQuery)
 {
        {
 Console.Write("{0,1} ", num);
            Console.Write("{0,1} ", num);
 }
        }
 }
    }
这里的第二步仅仅是创建查询条件(一个匿名函数),查询条件里面是不包含查询结果的。
真正的执行是在第三步里,这个感念,被称为“延迟执行”。
要LINQ查询强制立即执行可以使用ToArray和ToList方法。
 var numQuery =
    var numQuery =
 (from num in numbers
        (from num in numbers
 where (num % 2) == 0
         where (num % 2) == 0
 select num).ToList<int>();
         select num).ToList<int>();
如果要对数据源执行聚合函数的查询如:Count、Max、Average 和 First ,也会导致此LINQ执行强制立即查询。
对于一个LINQ查询,form关键字是必然存在的,select或group关键字也是必然存在的,
因为它必须是以select关键字开头和以select或group关键字结尾。
最简单的就如上面代码:
 var numQuery =
    var numQuery =
 from num in numbers
        from num in numbers
 select num;
        select num;
在某些情况下,源序列中的每个元素本身可能是序列,也可能包含序列,这时就需要用到 复合 from 子句 。
 public class Student
        public class Student
 {
        {
 public string LastName { get; set; }
            public string LastName { get; set; }
 public List<int> Scores { get; set; }
            public List<int> Scores { get; set; }
 }
        }

 static void Main()
        static void Main()
 {
        {

 // 建立数据源
            // 建立数据源
 List<Student> students = new List<Student>
            List<Student> students = new List<Student>
 {
            {
 new Student {LastName="Omelchenko", Scores= new List<int> {97, 72, 81, 60}},
               new Student {LastName="Omelchenko", Scores= new List<int> {97, 72, 81, 60}},
 new Student {LastName="O'Donnell", Scores= new List<int> {75, 84, 91, 39}},
               new Student {LastName="O'Donnell", Scores= new List<int> {75, 84, 91, 39}},
 new Student {LastName="Mortensen", Scores= new List<int> {88, 94, 65, 85}},
               new Student {LastName="Mortensen", Scores= new List<int> {88, 94, 65, 85}},
 new Student {LastName="Garcia", Scores= new List<int> {97, 89, 85, 82}},
               new Student {LastName="Garcia", Scores= new List<int> {97, 89, 85, 82}},
 new Student {LastName="Beebe", Scores= new List<int> {35, 72, 91, 70}}
               new Student {LastName="Beebe", Scores= new List<int> {35, 72, 91, 70}}
 };
            };

 // 使用复合 from 子句循环搜索出每个学生的各个成绩
            // 使用复合 from 子句循环搜索出每个学生的各个成绩
 var scoreQuery =
            var scoreQuery =
 from student in students
                 from student in students
 from score in student.Scores
                 from score in student.Scores
 where score > 90
                 where score > 90
 select new { Last = student.LastName, score };  // 匿名类型
                 select new { Last = student.LastName, score };  // 匿名类型
 
                 
 /*
            /*
 scoreQuery:
            scoreQuery:
 Omelchenko Score: 97
            Omelchenko Score: 97
 O'Donnell Score: 91
            O'Donnell Score: 91
 Mortensen Score: 94
            Mortensen Score: 94
 Garcia Score: 97
            Garcia Score: 97
 Beebe Score: 91
            Beebe Score: 91
 */
            */
 
            
 }
         }
复合 from 子句用于访问单个数据源中的内部集合。
不过,查询还可以包含多个可从独立数据源生成补充查询的 from 子句。
 static void Main()
        static void Main()
 {
        {

 char[] upperCase = { 'A', 'B', 'C' };
            char[] upperCase = { 'A', 'B', 'C' };
 char[] lowerCase = { 'x', 'y', 'z' };
            char[] lowerCase = { 'x', 'y', 'z' };

 var Query =
            var Query =
 from upper in upperCase
                from upper in upperCase
 from lower in lowerCase
                from lower in lowerCase
 select new { upper, lower };
                select new { upper, lower };

 foreach (var value in Query)
            foreach (var value in Query)
 Console.WriteLine("{0} , {1}", value.upper, value.lower);
                Console.WriteLine("{0} , {1}", value.upper, value.lower);

 Console.ReadKey();
            Console.ReadKey();
 
           
 /*
            /*
 Query:
            Query:
 A , x
            A , x
 A , y
            A , y
 A , z
            A , z
 B , x
            B , x
 B , y
            B , y
 B , z
            B , z
 C , x
            C , x
 C , y
            C , y
 C , z
            C , z
 */
            */

 }
        }
这段代码将会输出upperCase和lowerCase的笛卡尔乘积。

 static void Main()
        static void Main()
 {
        {
 int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
            int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
 
           
 // 搜索是偶数并且小于7的元素
            // 搜索是偶数并且小于7的元素
 var queryEvenNums =
            var queryEvenNums =
 from num in numbers
                    from num in numbers
 where IsEven(num) && num< 7
                    where IsEven(num) && num< 7
 select num;
                    select num;

 // 执行查询
            // 执行查询
 foreach (var s in queryEvenNums)
            foreach (var s in queryEvenNums)
 {
            {
 Console.Write(s.ToString() + " ");
                Console.Write(s.ToString() + " ");
 }
            }

 Console.ReadKey();
            Console.ReadKey();
 }
        }

 // 判断是否偶数
        // 判断是否偶数
 static bool IsEven(int i)
        static bool IsEven(int i)
 {
        {
 return i % 2 == 0;
            return i % 2 == 0;
 }
        }
 
       
 /*
        /*
 queryEvenNums:
        queryEvenNums:
 4 6 2 0
        4 6 2 0
 */
        */
也就是说,group子句出来的对象其实就是一个列表,
group子句由两个部分组成,group关键字之后的对象指名返回列表对象的类型,by关键字之后的是如果分组的条件。
分组条件的标识将会记录在返回对象列表的key属性中。
示例:
    
 数据源
数据源
 static void Main()
    static void Main()
 {
    {
 // 获取数据源
        // 获取数据源
 List<Student> students = GetStudents();
        List<Student> students = GetStudents();

 // 创建查询条件
        // 创建查询条件
 // booleanGroupQuery 变量的类型是 IEnumerable<IGrouping<bool, Student>>
        // booleanGroupQuery 变量的类型是 IEnumerable<IGrouping<bool, Student>>
 var booleanGroupQuery =
        var booleanGroupQuery =
 from student in students
            from student in students
 group student by student.Scores.Average() >= 80;
            group student by student.Scores.Average() >= 80;
 // 返回 student 类型的列表
        // 返回 student 类型的列表
 // 分组的条件是bool类型,是按照学生平均分是否大于80来进行分组的
        // 分组的条件是bool类型,是按照学生平均分是否大于80来进行分组的

 // 使用嵌套循环来取出值
        // 使用嵌套循环来取出值
 foreach (var studentGroup in booleanGroupQuery)
        foreach (var studentGroup in booleanGroupQuery)
 {
        {
 Console.WriteLine(studentGroup.Key == true ? "高分" : "低分"); //显示分组信息
            Console.WriteLine(studentGroup.Key == true ? "高分" : "低分"); //显示分组信息

 foreach (var student in studentGroup)
            foreach (var student in studentGroup)
 {
            {
 Console.WriteLine("   {0}. {1}:{2}", student.Last, student.First, student.Scores.Average());
                Console.WriteLine("   {0}. {1}:{2}", student.Last, student.First, student.Scores.Average());
 }
            }
 }
        }

 Console.ReadKey();
        Console.ReadKey();
 }
    }
 
   
 /*
    /*
 低分
    低分
 Omelchenko. Svetlana:77.5
       Omelchenko. Svetlana:77.5
 O'Donnell. Claire:72.25
       O'Donnell. Claire:72.25
 Garcia. Cesar:75.5
       Garcia. Cesar:75.5
 高分
    高分
 Mortensen. Sven:93.5
       Mortensen. Sven:93.5
 Garcia. Debra:88.25
       Garcia. Debra:88.25
 */
    */
在 group 或 select 子句中使用新标识符的用法有时称为“延续”。
 static void Main()
    static void Main()
 {
    {
 // 创建数据源
        // 创建数据源
 string[] words = { "apples", "blueberries", "oranges", "bananas", "apricots" };
        string[] words = { "apples", "blueberries", "oranges", "bananas", "apricots" };
 
       
 var wordGroups =
        var wordGroups =
 from w in words
            from w in words
 group w by w[0] into fruitGroup      // 以字符串的第一个字符来进行分组,并把结果列表送入fruitGroup。
            group w by w[0] into fruitGroup      // 以字符串的第一个字符来进行分组,并把结果列表送入fruitGroup。
 where fruitGroup.Count() >= 2
            where fruitGroup.Count() >= 2
 select new { FirstLetter = fruitGroup.Key, Words = fruitGroup.Count() };
            select new { FirstLetter = fruitGroup.Key, Words = fruitGroup.Count() };

 foreach (var item in wordGroups)
        foreach (var item in wordGroups)
 {
        {
 Console.WriteLine(" '{0}' 有 {1} 个。", item.FirstLetter, item.Words);
            Console.WriteLine(" '{0}' 有 {1} 个。", item.FirstLetter, item.Words);
 }
        }

 Console.ReadKey();
        Console.ReadKey();
 }
    }

 /*
    /*
 'a' 有 2 个。
     'a' 有 2 个。
 'b' 有 2 个。
     'b' 有 2 个。
 */
    */
 
 
 static void Main()
    static void Main()
 {
    {
 int[] number = {2,1,0,7,3,6,5,4};
        int[] number = {2,1,0,7,3,6,5,4};

 var Ascending =
        var Ascending =
 from num in number
            from num in number
 orderby num // 默认使用 ascending
            orderby num // 默认使用 ascending
 select num;
            select num;

 var Descendin =
        var Descendin =
 from num in number
            from num in number
 orderby num descending
            orderby num descending
 select num;
            select num;

 Console.WriteLine("升序:");
        Console.WriteLine("升序:");
 foreach (var item in Ascending)
        foreach (var item in Ascending)
 {
        {
 Console.Write(item + " " );
            Console.Write(item + " " );
 }
        }

 Console.WriteLine();
        Console.WriteLine();
 Console.WriteLine("降序:");
        Console.WriteLine("降序:");
 foreach (var item in Descendin)
        foreach (var item in Descendin)
 {
        {
 Console.Write(item + " ");
            Console.Write(item + " ");
 }
        }

 Console.ReadKey();
        Console.ReadKey();
 }
    }
 
   
 /*
    /*
 升序:
    升序:
 0 1 2 3 4 5 6 7
    0 1 2 3 4 5 6 7
 降序:
    降序:
 7 6 5 4 3 2 1 0
    7 6 5 4 3 2 1 0
 */
    */
 
唯一的要求是每个源中的元素需要共享某个可以进行比较以判断是否相等的值。
JOIN 链接一般能分为3种:
 数据源
数据源
内部连接:
 var innerJoinQuery =
    var innerJoinQuery =
 from category in categories
        from category in categories
 join prod in products on category.ID equals prod.CategoryID   //这里 category.ID 与 prod.CategoryID 有关联
        join prod in products on category.ID equals prod.CategoryID   //这里 category.ID 与 prod.CategoryID 有关联
 select new { ProductName = prod.Name, Category = category.Name };
        select new { ProductName = prod.Name, Category = category.Name }; 
这里出现了一个新的运算符: equals
这个运算符是LINQ独有的,执行等同链接,equals 与 == 运算符之间的一个重要的区别。
对于 equals,左键使用外部源序列,而右键使用内部源序列。外部源仅在 equals 的左侧位于范围内,
而内部源序列仅在其右侧位于范围内。
分组联接:
含有 into 表达式的 join 子句称为分组联接。
 var innerGroupJoinQuery =
    var innerGroupJoinQuery =
 from category in categories
        from category in categories
 join prod in products on category.ID equals prod.CategoryID into prodGroup
        join prod in products on category.ID equals prod.CategoryID into prodGroup
 select new { CategoryName = category.Name, Products = prodGroup };
        select new { CategoryName = category.Name, Products = prodGroup };
左外部联接:
在左外部联接中,将返回左侧源序列中的所有元素,即使它们在右侧序列中没有匹配的元素也是如此。
 var leftOuterJoinQuery =
    var leftOuterJoinQuery =
 from category in categories
        from category in categories
 join prod in products on category.ID equals prod.CategoryID into prodGroup
        join prod in products on category.ID equals prod.CategoryID into prodGroup
 from item in prodGroup.DefaultIfEmpty(new Product{Name = String.Empty, CategoryID = 0})
        from item in prodGroup.DefaultIfEmpty(new Product{Name = String.Empty, CategoryID = 0})
 select new { CatName = category.Name, ProdName = item.Name };
            select new { CatName = category.Name, ProdName = item.Name };
 string[] strings =
    string[] strings =
 {
        {
 "A penny saved is a penny earned.",
            "A penny saved is a penny earned.",
 "The early bird catches the worm.",
            "The early bird catches the worm.",
 "The pen is mightier than the sword."
            "The pen is mightier than the sword."
 };
        };

 // 这里words是分解
    // 这里words是分解
 // w是word的小写版本
    // w是word的小写版本
 var earlyBirdQuery =
    var earlyBirdQuery =
 from sentence in strings
        from sentence in strings
 let words = sentence.Split(' ')
        let words = sentence.Split(' ')
 from word in words
        from word in words
 let w = word.ToLower()
        let w = word.ToLower()
 where w[0] == 'a' || w[0] == 'e'
        where w[0] == 'a' || w[0] == 'e'
 || w[0] == 'i' || w[0] == 'o'
            || w[0] == 'i' || w[0] == 'o'
 || w[0] == 'u'
            || w[0] == 'u'
 select word;
        select word;
所有 LINQ 查询操作都由以下三个不同的操作组成:
1.获取数据源。
2.创建查询。
3.执行查询。
 static void Main()
    static void Main() {
    { // 1. 数据源
        // 1. 数据源 int[] numbers = new int[7] { 0, 1, 2, 3, 4, 5, 6 };
        int[] numbers = new int[7] { 0, 1, 2, 3, 4, 5, 6 };
 // 2. 创建查询
        // 2. 创建查询 // 这里numQuery变量的类型为IEnumerable<int>
        // 这里numQuery变量的类型为IEnumerable<int> var numQuery =
        var numQuery = from num in numbers
            from num in numbers where (num % 2) == 0
            where (num % 2) == 0 select num;
            select num;
 // 3. 执行查询
        // 3. 执行查询 foreach (int num in numQuery)
        foreach (int num in numQuery) {
        { Console.Write("{0,1} ", num);
            Console.Write("{0,1} ", num); }
        } }
    }这里的第二步仅仅是创建查询条件(一个匿名函数),查询条件里面是不包含查询结果的。
真正的执行是在第三步里,这个感念,被称为“延迟执行”。
要LINQ查询强制立即执行可以使用ToArray和ToList方法。
 var numQuery =
    var numQuery = (from num in numbers
        (from num in numbers where (num % 2) == 0
         where (num % 2) == 0 select num).ToList<int>();
         select num).ToList<int>();如果要对数据源执行聚合函数的查询如:Count、Max、Average 和 First ,也会导致此LINQ执行强制立即查询。
LINQ 的关键字:
对于一个LINQ查询,form关键字是必然存在的,select或group关键字也是必然存在的,
因为它必须是以select关键字开头和以select或group关键字结尾。
FORM 子句:
form子句需要指定查询或子查询的数据源和一个本地范围变量。最简单的就如上面代码:
 var numQuery =
    var numQuery = from num in numbers
        from num in numbers select num;
        select num;在某些情况下,源序列中的每个元素本身可能是序列,也可能包含序列,这时就需要用到 复合 from 子句 。
 public class Student
        public class Student {
        { public string LastName { get; set; }
            public string LastName { get; set; } public List<int> Scores { get; set; }
            public List<int> Scores { get; set; } }
        }
 static void Main()
        static void Main() {
        {
 // 建立数据源
            // 建立数据源 List<Student> students = new List<Student>
            List<Student> students = new List<Student> {
            { new Student {LastName="Omelchenko", Scores= new List<int> {97, 72, 81, 60}},
               new Student {LastName="Omelchenko", Scores= new List<int> {97, 72, 81, 60}}, new Student {LastName="O'Donnell", Scores= new List<int> {75, 84, 91, 39}},
               new Student {LastName="O'Donnell", Scores= new List<int> {75, 84, 91, 39}}, new Student {LastName="Mortensen", Scores= new List<int> {88, 94, 65, 85}},
               new Student {LastName="Mortensen", Scores= new List<int> {88, 94, 65, 85}}, new Student {LastName="Garcia", Scores= new List<int> {97, 89, 85, 82}},
               new Student {LastName="Garcia", Scores= new List<int> {97, 89, 85, 82}}, new Student {LastName="Beebe", Scores= new List<int> {35, 72, 91, 70}}
               new Student {LastName="Beebe", Scores= new List<int> {35, 72, 91, 70}} };
            };
 // 使用复合 from 子句循环搜索出每个学生的各个成绩
            // 使用复合 from 子句循环搜索出每个学生的各个成绩 var scoreQuery =
            var scoreQuery = from student in students
                 from student in students from score in student.Scores
                 from score in student.Scores where score > 90
                 where score > 90 select new { Last = student.LastName, score };  // 匿名类型
                 select new { Last = student.LastName, score };  // 匿名类型 
                  /*
            /* scoreQuery:
            scoreQuery: Omelchenko Score: 97
            Omelchenko Score: 97 O'Donnell Score: 91
            O'Donnell Score: 91 Mortensen Score: 94
            Mortensen Score: 94 Garcia Score: 97
            Garcia Score: 97 Beebe Score: 91
            Beebe Score: 91 */
            */ 
             }
         }复合 from 子句用于访问单个数据源中的内部集合。
不过,查询还可以包含多个可从独立数据源生成补充查询的 from 子句。
 static void Main()
        static void Main() {
        {
 char[] upperCase = { 'A', 'B', 'C' };
            char[] upperCase = { 'A', 'B', 'C' }; char[] lowerCase = { 'x', 'y', 'z' };
            char[] lowerCase = { 'x', 'y', 'z' };
 var Query =
            var Query = from upper in upperCase
                from upper in upperCase from lower in lowerCase
                from lower in lowerCase select new { upper, lower };
                select new { upper, lower };
 foreach (var value in Query)
            foreach (var value in Query) Console.WriteLine("{0} , {1}", value.upper, value.lower);
                Console.WriteLine("{0} , {1}", value.upper, value.lower);
 Console.ReadKey();
            Console.ReadKey(); 
            /*
            /* Query:
            Query: A , x
            A , x A , y
            A , y A , z
            A , z B , x
            B , x B , y
            B , y B , z
            B , z C , x
            C , x C , y
            C , y C , z
            C , z */
            */
 }
        }这段代码将会输出upperCase和lowerCase的笛卡尔乘积。
WHERE 子句:
where子句用于指定将在查询表达式中返回数据源中的哪些元素。
 static void Main()
        static void Main() {
        { int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
            int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 
            // 搜索是偶数并且小于7的元素
            // 搜索是偶数并且小于7的元素 var queryEvenNums =
            var queryEvenNums = from num in numbers
                    from num in numbers where IsEven(num) && num< 7
                    where IsEven(num) && num< 7 select num;
                    select num;
 // 执行查询
            // 执行查询 foreach (var s in queryEvenNums)
            foreach (var s in queryEvenNums) {
            { Console.Write(s.ToString() + " ");
                Console.Write(s.ToString() + " "); }
            }
 Console.ReadKey();
            Console.ReadKey(); }
        }
 // 判断是否偶数
        // 判断是否偶数 static bool IsEven(int i)
        static bool IsEven(int i) {
        { return i % 2 == 0;
            return i % 2 == 0; }
        } 
        /*
        /* queryEvenNums:
        queryEvenNums: 4 6 2 0
        4 6 2 0 */
        */GROUP 子句
group子句返回一个 IGrouping(TKey, TElement) 对象序列,这些对象包含零个或更多个与该组的键值匹配的项。也就是说,group子句出来的对象其实就是一个列表,
group子句由两个部分组成,group关键字之后的对象指名返回列表对象的类型,by关键字之后的是如果分组的条件。
分组条件的标识将会记录在返回对象列表的key属性中。
示例:
 数据源
数据源 static void Main()
    static void Main() {
    { // 获取数据源
        // 获取数据源 List<Student> students = GetStudents();
        List<Student> students = GetStudents();
 // 创建查询条件
        // 创建查询条件 // booleanGroupQuery 变量的类型是 IEnumerable<IGrouping<bool, Student>>
        // booleanGroupQuery 变量的类型是 IEnumerable<IGrouping<bool, Student>> var booleanGroupQuery =
        var booleanGroupQuery = from student in students
            from student in students group student by student.Scores.Average() >= 80;
            group student by student.Scores.Average() >= 80; // 返回 student 类型的列表
        // 返回 student 类型的列表 // 分组的条件是bool类型,是按照学生平均分是否大于80来进行分组的
        // 分组的条件是bool类型,是按照学生平均分是否大于80来进行分组的
 // 使用嵌套循环来取出值
        // 使用嵌套循环来取出值 foreach (var studentGroup in booleanGroupQuery)
        foreach (var studentGroup in booleanGroupQuery) {
        { Console.WriteLine(studentGroup.Key == true ? "高分" : "低分"); //显示分组信息
            Console.WriteLine(studentGroup.Key == true ? "高分" : "低分"); //显示分组信息
 foreach (var student in studentGroup)
            foreach (var student in studentGroup) {
            { Console.WriteLine("   {0}. {1}:{2}", student.Last, student.First, student.Scores.Average());
                Console.WriteLine("   {0}. {1}:{2}", student.Last, student.First, student.Scores.Average()); }
            } }
        }
 Console.ReadKey();
        Console.ReadKey(); }
    } 
    /*
    /* 低分
    低分 Omelchenko. Svetlana:77.5
       Omelchenko. Svetlana:77.5 O'Donnell. Claire:72.25
       O'Donnell. Claire:72.25 Garcia. Cesar:75.5
       Garcia. Cesar:75.5 高分
    高分 Mortensen. Sven:93.5
       Mortensen. Sven:93.5 Garcia. Debra:88.25
       Garcia. Debra:88.25 */
    */INTO 子句:
into 为上下文关键字创建一个临时标识符,以便将 group、join 或 select 子句的结果存储到新的标识符中。在 group 或 select 子句中使用新标识符的用法有时称为“延续”。
 static void Main()
    static void Main() {
    { // 创建数据源
        // 创建数据源 string[] words = { "apples", "blueberries", "oranges", "bananas", "apricots" };
        string[] words = { "apples", "blueberries", "oranges", "bananas", "apricots" }; 
        var wordGroups =
        var wordGroups = from w in words
            from w in words group w by w[0] into fruitGroup      // 以字符串的第一个字符来进行分组,并把结果列表送入fruitGroup。
            group w by w[0] into fruitGroup      // 以字符串的第一个字符来进行分组,并把结果列表送入fruitGroup。 where fruitGroup.Count() >= 2
            where fruitGroup.Count() >= 2 select new { FirstLetter = fruitGroup.Key, Words = fruitGroup.Count() };
            select new { FirstLetter = fruitGroup.Key, Words = fruitGroup.Count() };
 foreach (var item in wordGroups)
        foreach (var item in wordGroups) {
        { Console.WriteLine(" '{0}' 有 {1} 个。", item.FirstLetter, item.Words);
            Console.WriteLine(" '{0}' 有 {1} 个。", item.FirstLetter, item.Words); }
        }
 Console.ReadKey();
        Console.ReadKey(); }
    }
 /*
    /* 'a' 有 2 个。
     'a' 有 2 个。 'b' 有 2 个。
     'b' 有 2 个。 */
    */
ORDERBY 子句:
orderby子句可使返回的序列或子序列(组)按升序或降序排序。 static void Main()
    static void Main() {
    { int[] number = {2,1,0,7,3,6,5,4};
        int[] number = {2,1,0,7,3,6,5,4};
 var Ascending =
        var Ascending = from num in number
            from num in number orderby num // 默认使用 ascending
            orderby num // 默认使用 ascending select num;
            select num;
 var Descendin =
        var Descendin = from num in number
            from num in number orderby num descending
            orderby num descending select num;
            select num;
 Console.WriteLine("升序:");
        Console.WriteLine("升序:"); foreach (var item in Ascending)
        foreach (var item in Ascending) {
        { Console.Write(item + " " );
            Console.Write(item + " " ); }
        }
 Console.WriteLine();
        Console.WriteLine(); Console.WriteLine("降序:");
        Console.WriteLine("降序:"); foreach (var item in Descendin)
        foreach (var item in Descendin) {
        { Console.Write(item + " ");
            Console.Write(item + " "); }
        }
 Console.ReadKey();
        Console.ReadKey(); }
    } 
    /*
    /* 升序:
    升序: 0 1 2 3 4 5 6 7
    0 1 2 3 4 5 6 7 降序:
    降序: 7 6 5 4 3 2 1 0
    7 6 5 4 3 2 1 0 */
    */
JOIN 子句:
join子句可以将来自不同源序列并且在对象模型中没有直接关系的元素相关联。唯一的要求是每个源中的元素需要共享某个可以进行比较以判断是否相等的值。
JOIN 链接一般能分为3种:
 数据源
数据源内部连接:
 var innerJoinQuery =
    var innerJoinQuery = from category in categories
        from category in categories join prod in products on category.ID equals prod.CategoryID   //这里 category.ID 与 prod.CategoryID 有关联
        join prod in products on category.ID equals prod.CategoryID   //这里 category.ID 与 prod.CategoryID 有关联 select new { ProductName = prod.Name, Category = category.Name };
        select new { ProductName = prod.Name, Category = category.Name }; 这里出现了一个新的运算符: equals
这个运算符是LINQ独有的,执行等同链接,equals 与 == 运算符之间的一个重要的区别。
对于 equals,左键使用外部源序列,而右键使用内部源序列。外部源仅在 equals 的左侧位于范围内,
而内部源序列仅在其右侧位于范围内。
分组联接:
含有 into 表达式的 join 子句称为分组联接。
 var innerGroupJoinQuery =
    var innerGroupJoinQuery = from category in categories
        from category in categories join prod in products on category.ID equals prod.CategoryID into prodGroup
        join prod in products on category.ID equals prod.CategoryID into prodGroup select new { CategoryName = category.Name, Products = prodGroup };
        select new { CategoryName = category.Name, Products = prodGroup };左外部联接:
在左外部联接中,将返回左侧源序列中的所有元素,即使它们在右侧序列中没有匹配的元素也是如此。
 var leftOuterJoinQuery =
    var leftOuterJoinQuery = from category in categories
        from category in categories join prod in products on category.ID equals prod.CategoryID into prodGroup
        join prod in products on category.ID equals prod.CategoryID into prodGroup from item in prodGroup.DefaultIfEmpty(new Product{Name = String.Empty, CategoryID = 0})
        from item in prodGroup.DefaultIfEmpty(new Product{Name = String.Empty, CategoryID = 0}) select new { CatName = category.Name, ProdName = item.Name };
            select new { CatName = category.Name, ProdName = item.Name };LET 子句:
在查询表达式中,let子句 存储子表达式的结果有时很有用,这样可以在随后的子句中使用。 string[] strings =
    string[] strings = {
        { "A penny saved is a penny earned.",
            "A penny saved is a penny earned.", "The early bird catches the worm.",
            "The early bird catches the worm.", "The pen is mightier than the sword."
            "The pen is mightier than the sword." };
        };
 // 这里words是分解
    // 这里words是分解 // w是word的小写版本
    // w是word的小写版本 var earlyBirdQuery =
    var earlyBirdQuery = from sentence in strings
        from sentence in strings let words = sentence.Split(' ')
        let words = sentence.Split(' ') from word in words
        from word in words let w = word.ToLower()
        let w = word.ToLower() where w[0] == 'a' || w[0] == 'e'
        where w[0] == 'a' || w[0] == 'e' || w[0] == 'i' || w[0] == 'o'
            || w[0] == 'i' || w[0] == 'o' || w[0] == 'u'
            || w[0] == 'u' select word;
        select word; 
                    
                     
                    
                 
                    
                

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号