zoukankan      html  css  js  c++  java
  • Linq基础知识小记三

    1、子查询

    Linq中的子查询思想和Sql中的子查询其实差不多,

    对于方法语法,一个子查询包含在另一个子查询的Lambda表达式中,代码如下:

    string[] names = { "James", "Kobe", "Curry", "Durrent" };
    IEnumerable<string> result = names.OrderBy(n => n.Split().Last());

    n.Split().Last()就是一个子查询

    下面通过一个例子来讲解Linq子查询的两种不同的方式.找出一个IEnumerable<T>长度中最长的字符串

    string[] names = { "James", "Kobe", "Curry", "Durrent" };
    //方法语法
    IEnumerable<string> method = names.Where(n=>n==(names.OrderBy(l => l.Length)).Last());
    foreach (var n in method)
    {
       Console.WriteLine(n);
    }

    string[] names = { "James", "Kobe", "Curry", "Durrent" };
    //表达式语法
    var express = from n in names
    where n ==
    (from i in names orderby i.Length descending select i).First()
    select n;
    foreach (var n in express)
    {
       Console.WriteLine(n);
    }

    2、本地查询和解释查询

    本地查询(Linq To Object)和解释查询(Linq To Sql)对于子查询的处理方式不一样.

    (1)、本地查询(Linq To Object)对于外部查询的每一次循环,子查询都会被重新被执行一次,所以像上面的案例当外部查询循环每执行一次,内部子查询就会被重新执行一次,这是很严重的性能浪费,所以上面的案例可以这样改写,代码如下:

    string[] names = { "James", "Kobe", "Curry", "Durrent" };
    int shortest = names.Max(n => n.Length);
    //表达式语法
    var express = from n in names
    where n.Length == shortest
         select n;
    foreach (var n in express)
    {
         Console.WriteLine(n);
    }

    (2)、解释查询处理子查询的方式和本地查询就截然不同,在解释查询中,外部查询和子查询是作为一个单元进行处理的,这样就只需要联结一次数据库就行了,所以上面的案例适合解释查询,不适合本地查询.

    (3)、子查询不会改变Linq延迟执行的特性,因为子查询总是间接调用的.

    2、Linq查询创建攻略

    常用的Linq查询方式有三种两种已经在前面用到过了,下面有个案例,去除一个字符串数组中的所有的元音字母,然后对长度大于1的元素进行按长度排序.

    第一种:链式查询

    string[] names = { "James", "Kobe", "Curry", "Durrent" };
    IEnumerable<string> result = names.Select(n => Regex.Replace(n, "[aeiou]", "")).Where(n => n.Length > 1)
    .OrderBy(n => n.Length);
    foreach (var n in result)
    {
          Console.WriteLine(n);
    }

    第二种:类似Sql子查询的查询

    string[] names = { "James", "Kobe", "Curry", "Durrent" };
    IEnumerable<string> result = from n in
    (
          from n in names
          select Regex.Replace(n, "[aeiou]", "")
    )
    where n.Length > 1
    orderby n.Length
    select n;
                                          
    foreach (var n in result)
    {
          Console.WriteLine(n);
    }

    第三种:重点讲解,into关键字

    select关键字或者group关键字意味着查询的结束,但是into关键字可以使我们在结果投影之后继续操作,它是对分步构建查询表达式的一种简写方式,代码如下:

    string[] names = { "James", "Kobe", "Curry", "Durrent" };
    IEnumerable<string> result = from n in names
    select Regex.Replace(n, "[aeiou]", "")
    into noVowel
    where noVowel.Length > 1
    orderby noVowel.Length
    select noVowel;                   
    foreach (var n in result)
    {
       Console.WriteLine(n);
    }

    3、数据转换

    Linq的数据转换,也叫结果投影。到目前为止,我们只看到了单个标量的元素,但是通过对象初始化器和匿名类型和let关键字我们能输出更复杂的数据类型

    (1)、对象初始化器

    string[] names = { "James", "Kobe", "Curry", "Durrent" };
    IEnumerable<TempProjection> temp = from n in names
    select new TempProjection
    {
            Original = n,
            Vowelless = Regex.Replace(n, "[aeiou]", "")
    };
    
    IEnumerable<string> query =
    from n in temp
    where n.Vowelless.Length > 3
    select n.Original;
    
    foreach (var n in query)
    {
          Console.WriteLine(n);
    }
    
    class TempProjection
    {
       public string Original { get; set; }
       public string Vowelless { get; set; }
    }

    (2)、匿名类型

    匿名类型其实和对象初始化其差不多,就是我们不用创建类型,让编译器来帮助我们创建,代码如下:

    string[] names = { "James", "Kobe", "Curry", "Durrent" };
    var  temp = from n in names //注意这里只能用关键字var 
    select new 
    {
            Original = n,
            Vowelless = Regex.Replace(n, "[aeiou]", "")
    };
    
    IEnumerable<string> query =
    from n in temp
    where n.Vowelless.Length > 3
    select n.Original;
    
    foreach (var n in query)
    {
          Console.WriteLine(n);
    }

    使用匿名类型配合关键字var能帮助我们极大的减少代码量.

    (3)、Let关键字

    Let关键字能帮助我们引入新的变脸的同时,保持范围变量,示例代码如下:

    string[] names = { "James", "Kobe", "Curry", "Durrent" };
    var temp = from n in names //注意这里只能用关键字var 
    let vowelless = Regex.Replace(n, "[aeiou]", "")
    where vowelless.Length > 1
    select n;
    
    foreach (var n in temp)
    {
        Console.WriteLine(n);
    }

    let关键字非常灵活和方便,就像例子看到的那样。而且,我们可以使用多个let关键字,并且后面的 let表达式可以引用前一个let关键字引入的变量。

  • 相关阅读:
    LeetCode 1245. Tree Diameter
    LeetCode 1152. Analyze User Website Visit Pattern
    LeetCode 1223. Dice Roll Simulation
    LeetCode 912. Sort an Array
    LeetCode 993. Cousins in Binary Tree
    LeetCode 1047. Remove All Adjacent Duplicates In String
    LeetCode 390. Elimination Game
    LeetCode 1209. Remove All Adjacent Duplicates in String II
    LeetCode 797. All Paths From Source to Target
    LeetCode 1029. Two City Scheduling
  • 原文地址:https://www.cnblogs.com/GreenLeaves/p/7602913.html
Copyright © 2011-2022 走看看