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关键字引入的变量。

时间: 2024-10-10 02:06:19

Linq基础知识小记三的相关文章

Linq基础知识小记

1.LINQ(语言级集成查询)的作用就是提供一种统一且对称的方式,让程序员在广义的数据上获取和操作数据.广义的数据包括XML文档数据.元数据.System.Data.dll和System.Data.SqlClient.dll提供的DataSet和DataTable等数据.内存数据(Array.Collection)等. 2.Linq To Object是针对实现了IEnumerable<T>的对象操作或获取数据的功能,代码如下: (1).通过Enumerable的实例方法实现查询 string

web基础知识(三)关于ajax,Jquery传值最基础东西

今天补充一下两个小功能,一个是关于radio单选框的情况,如何在前面选了后,传到后台,编辑修改的时候再次传回来,并且在当时选的那个上:再一个就是关于添加小标签的时候添加接着弹出在下面,并点击出现删除. 一:radio 1 <div class="newlylist"> 2 <div class="newlyhead">图示商品:</div> 3 <div class="newlycontent">&

spring基础知识(三)——aop

spring基础知识(三)--aop面向切面编程 1.概念术语 aop面向切面编程(Aspect ariented Programming) 在开始之前,需要理解Spring aop 的一些基本的概念术语(总结的个人理解,并非Spring官方定义): 切面(aspect):用来切插业务方法的类. 连接点(joinpoint):是切面类和业务类的连接点,其实就是封装了业务方法的一些基本属性,作为通知的参数来解析. 通知(advice):在切面类中,声明对业务方法做额外处理的方法. 切入点(poin

Java基础知识的三十个经典问答

Java基础知识的三十个经典问答 1.面向对象的特点 抽象: 抽象是或略一个主题中与当前目标的无关的因素,一边充分考虑有关的内容.抽象并不能解决目标中所有的问题,只能选择其中的一部分,忽略其他的部分.抽象包含两个方面:一是过程抽象:一是数据抽象. 继承 继承是一种联接类的层次模型,允许和鼓励类的重用,提供了一种明确的共性的方法.对象的一个新类可以从现有的类中派生,这叫做类的继承.心累继承了原始类 的特性,新类称为原始类的派生类或者是子类,原始类称为新类的基类或者父类.子类可以从父类那里继承父类的

C#编译基础知识(三)

本文章我们将来重点介绍强命名程序集,强命名程序集的出现其实是为解决版本控制问题,比如说,在新版程序集发布后,我们希望在系统中对旧程序集的引用继续保留,而有些地方又可以引用新的程序集,再比如说不同的公司提供了不同功能的程序集,这些类库存放在一个公共目录,有时候可能会出现名称相同的情况.使用强命名程序集可以解决这些问题,一个强命名的程序集是靠公钥标示.程序集版本号.区域属性.程序集名称这四个属性来唯一标识的,这样一来,新发布的库文件版本与前面发布的不同,不同的版本引用可以在元数据里面标识,相互不会受

线程基础知识系列(三)线程的同步

本文是系列的第三篇,前面2篇,主要是针对单个线程如何管理,启动等,没有过多涉及多个线程是如何协同工作的. 线程基础知识系列(二)线程的管理 :线程的状态,控制,休眠,Interrupt,yield等 线程基础知识系列(一)线程的创建和启动  :线程的创建和启动,join(),daemon线程,Callable任务. 本文的主要内容 何谓线程安全? 何谓共享可变变量? 认识synchronized关键字 认识Lock synchronized vs Lock 1.何谓线程安全 多线程是把双刃剑,带

《Java核心技术 卷1 基础知识》三

<Java核心技术 卷1 基础知识> 第六章 接口和内部类 接口不是类,而是对类的的一组需求描述. 接口不能包含实例域--接口没有实例 可以将接口看作没有实例域的抽象类 要将类声明为实现某个接口,需要使用关键字implements. 类实现一个接口的具体步骤为: 1)使用implements关键字进行声明要实现的接口 2)对接口中的所有方法进行定义 接口中的所有方法默认为public 但在实现接口时需要声明为public 这里介绍了Comparable接口,该接口只有一个方法,compareT

Python基础知识(三) Python编码、变量、if和while语句

Python入门知识 一.第一句Python代码 在Linux下/home/test目录下创建hello.py文件,内容如下: [[email protected] ~]# mkdir /home/test [[email protected] ~]# cd /home/test [[email protected] test]# cat hello.py print("Hello World!") 执行hello.py文件,得到以下内容: [[email protected] tes

.NET Framework基础知识(三)(转载)

1.正则表达式:用一串字符验证是否符合一种规范,这个规范就是正则表达式. 2.正则表达式中常用的元字符: . 匹配除换行符以外的任意字符 \w 匹配字母或数字或下划线或汉字 \s 匹配空白符 \d 匹配数字 \b 匹配单词的开始或结束 ^ 匹配字符串的开始 $ 匹配字符串的结束 例: string regstr = @"^\d\d\d$"; Regex reg = new Regex(regstr); string intputstr = "163"; if (re