LINQ之路 1: LINQ介绍
LINQ是.NET Framework 3.5的新特性,其全称是 Language Integrated Query,即语言集成查询,是指将查询功能和语言结合起来。从而为我们提供一种统一的方式,让我们能在C#或VB.NET语言中直接查询和操作各种数据。
LINQ的作用
作为软件开发人员,我们很大一部分时间都花在了获取和操作数据上面。而说到数据,我们会自然而然地想到包含在关系数据库里的信息、使用的XML文档、保存在本地的DataSet、内存中的List列表等等。通常我们会对数据进行过滤和定位,查询出符合要求的那一部分数据。
在.NET 3.5之前的版本中,与特定的数据类型打交道时,我们要使用特定特定命名空间下的特定类型。如下表列出了操作各种常见类型的API
|
目标数据 |
操作数据的.NET类型 |
|
关系数据 |
System.Data.dll和System.Data.SqlClient.dll |
|
XML文档数据 |
System.Xml.dll |
|
元数据 |
System.Reflection命名空间 |
|
内存对象集合 |
System.Array和 System.Collection/System.Collection.Generic命名空间 |
虽然这些操作数据的方法本身没有问题,比如我们都会直接使用ADO.NET、XML命名空间、反射服务以及各种集合类型。但是本质的问题在于,这些API的每一种本身只是一座孤岛,提供了很少的集成方式。比如我们可以把ADO.NET DataSet保存为XML,然后通过System.Xml命名空间来操作。但是各API之间没有替代品,我们没法用ADO.NET API来操作XML,也不能用System.Array来操作关系数据。
LINQ(语言级集成查询)的意图就是提供一种统一且对称的方式,让程序员在广义的数据上获取和操作数据。通过使用LINQ,我们能够在C#编程语言内直接创建被称为“查询表达式(query expression)”的实体。这些查询表达式是基于许多查询运算符(query operator)的,而且是有意设计成类似SQL表达式的。并且,查询表达式可以用来与多种数据进行交互,以一种统一的方式来操作各种数据。
严格来说,LINQ是用来描述数据访问总体方式的术语。LINQ to Object是针对实现了IEnumerable<T>的对象的LINQ;LINQ to SQL是针对关系数据库的LINQ;LINQ to XML是针对XML文档的LINQ。
LINQ除了提供一个统一的API来操作各种数据,并且为我们提供了编译时类型检查和动态创建查询表达式的能力。
从这里开始
LINQ中最基本的数据单元是sequences和elements。一个sequence是实现了IEnumerable<T>的对象,而一个element是sequence中的每一个元素。如下,names就是一个sequence,”Tom”,“Dick”和”Harry”则是elements。
string[] names = { "Tom", "Dick", "Harry" };
一个查询运算符就是用来转换sequence的方法。一个典型的查询运算符接收一个输入sequence并输出一个转换之后的sequence。在System.Linq.Enumerable类中,总共定义了40来个查询运算符----全部用扩展方法来实现,他们被称为标准查询运算符。
一个查询则是由查询运算符来转换sequence的一个表达式,最简单的查询由一个input sequence和一个查询运算符组成。比如:
string[] names = { "Tom", "Dick", "Harry" };
// 获取所有长度大于等于4的名字
IEnumerable<string> filteredNames = System.Linq.Enumerable.Where(
names, n => n.Length >= );
foreach (string n in filteredNames)
Console.WriteLine(n);
输出:
Dick
Harry
因为查询运算符是以扩展方法实现的,所以我们可以直接在names对象上调用Where:
// 获取所有长度大于等于4的名字
IEnumerable<string> filteredNames = names.Where(n => n.Length >= );
我们可以通过使用var关键字来进一步简写我们的query:
var filteredNames = names.Where(n => n.Length >= );
注:在初学LINQ时,var关键字可能会影响可读性,特别是在没有IDE和智能提示的时候,因而如果可能,我会在本系列的开始尽量使用确切的返回类型。
大部分查询运算符都接受一个lambda表达式作为参数,lambda表达式决定了查询的行为特性和结果。在上例中,lambda表达式为:
n => n.Length >=
Lambda表达式格式为:(parameters) => expression-or-statement-block
在这里的lambda表达式中,输入参数n对应了names数组的每一个元素,其类型为string。Where运算符要求lambda表达式返回一个bool值,当结果为true时,表示该元素会包含在输出sequence中。这里是Where运算符的方法签名:
public static IEnumerable<TSource> Where<TSource>
(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
下面的query获取所有包含字母a的名字:
string[] names = { "Tom", "Dick", "Harry" };
IEnumerable<string> filteredNames = names.Where(n => n.Contains("a"));
foreach (string name in filteredNames)
Console.WriteLine(name); // Harry
到现在为止,我们通过使用扩展方法和lambda表达式来建立了LINQ query。我们很快就能看到,这种策略非常的灵活和适合query的创建,因为我们可以级联的使用查询运算符。通常,这种方法被称为LINQ方法语法(英文著作中称为fluent syntax)。C#还提供了另外一种书写query的语法,叫做查询表达式语法(英文著作中称为query expression syntax),下面是一个用查询表达式语法建立的query,让我们先睹为快:
IEnumerable<string> filteredNames = from n in names
where n.Contains("a")
select n; // Harry
方法语法和查询表达式语法是互为补充的,在之后的LINQ方法语法和查询语法一篇中,我们会详解他们的联系和区别。
LINQ之路 1: LINQ介绍的更多相关文章
- LINQ之路 7:子查询、创建策略和数据转换
在前面的系列中,我们已经讨论了LINQ简单查询的大部分特性,了解了LINQ的支持计术和语法形式.至此,我们应该可以创建出大部分相对简单的LINQ查询.在本篇中,除了对前面的知识做个简单的总结,还会介绍 ...
- LINQ之路 4:LINQ方法语法
书写LINQ查询时又两种语法可供选择:方法语法(Fluent Syntax)和查询语法(Query Expression). LINQ方法语法是非常灵活和重要的,我们在这里将描述使用链接查询运算符的方 ...
- LINQ之路(3):LINQ扩展
本篇文章将从三个方面来进行LINQ扩展的阐述:扩展查询操作符.自定义查询操作符和简单模拟LINQ to SQL. 1.扩展查询操作符 在实际的使用过程中,Enumerable或Queryable中的扩 ...
- LINQ之路(2):LINQ to SQL本质
LINQ之路(2):LINQ to SQL本质 在前面一篇文章中回顾了LINQ基本语法规则,在本文将介绍LINQ to SQL的本质.LINQ to SQL是microsoft针对SQL Server ...
- LINQ之路16:LINQ Operators之集合运算符、Zip操作符、转换方法、生成器方法
本篇将是关于LINQ Operators的最后一篇,包括:集合运算符(Set Operators).Zip操作符.转换方法(Conversion Methods).生成器方法(Generation M ...
- LINQ之路15:LINQ Operators之元素运算符、集合方法、量词方法
本篇继续LINQ Operators的介绍,包括元素运算符/Element Operators.集合方法/Aggregation.量词/Quantifiers Methods.元素运算符从一个sequ ...
- LINQ之路10:LINQ to SQL 和 Entity Framework(下)
在本篇中,我们将接着上一篇“LINQ to SQL 和 Entity Framework(上)”的内容,继续使用LINQ to SQL和Entity Framework来实践“解释查询”,学习这些技术 ...
- [转]LINQ之路系列博客导航
分享一个学习Linq的好博客:Linq之路
- LINQ之路系列文章导读
本系列文章将会分为3篇来进行阐述,如下: LINQ之路(1):LINQ基础 LINQ之路(2):LINQ to SQL本质 LINQ之路(3):LINQ扩展
- LINQ之路11:LINQ Operators之过滤(Filtering)
在本系列博客前面的篇章中,已经对LINQ的作用.C# 3.0为LINQ提供的新特性,还有几种典型的LINQ技术:LINQ to Objects.LINQ to SQL.Entity Framework ...
随机推荐
- 14 个 grep 命令的例子 【转】
转自:https://linux.cn/article-5453-1.html 编译自:http://www.linuxtechi.com/linux-grep-command-with-14-dif ...
- MySQL存储引擎中的MyISAM和InnoDB区别详解
在使用MySQL的过程中对MyISAM和InnoDB这两个概念存在了些疑问,到底两者引擎有何分别一直是存在我心中的疑问.为了解开这个谜题,搜寻了网络,找到了如下信息: MyISAM是MySQL的默认数 ...
- HDU 4453:Looploop(Splay各种操作)
http://acm.hdu.edu.cn/showproblem.php?pid=4453 题意:很多种操作:1.add x,将从光标起的 k2 个数全部加上 x:2.reverse,将从光标起的 ...
- Ajax的基本语法
//声明XMLHttpRequest var xmlHttp = null; // 创建XMLHttpRequest对象兼容所有浏览器 function createXMLHttpR ...
- mysql聚集索引的优缺点
聚簇索引并不是一种单独的索引类型,而是一种数据存储方式(不是数据结构,而是存储结构),具体细节依赖于其实现方式,但innodb的聚簇索引实际上是在同一个结构中保存了btree索引和数据行. 当表有索引 ...
- 20145227 《Java程序设计》第8周学习总结
20145227 <Java程序设计>第8周学习总结 教材学习内容总结 第十四章 NIO与NIO2 NIO即New IO.java从JDK1.4开始提供了NIO,在JAVA SE 7 中又 ...
- asp.net 分页-利用后台直接生成html分页
一直想做一个属于自己的分页, 1:我试过用datapage,虽然是很好用,但是必须要配合datalist才能使用,感觉不太好 2:自己写分页控件,目前正在摸索中,关键是怎么分页的问题,有的是用data ...
- LA 3704 Cellular Automaton
题意概述: 等价地,本题可以转化为下面的问题: 考虑$n \times n$的$0-1$矩阵$A$,在第$i$行上第$[-d+i, d+i]$(模$n$意义下)列对应的元素为$1$,其余为$0$.求$ ...
- Dungeon Master 分类: 搜索 POJ 2015-08-09 14:25 4人阅读 评论(0) 收藏
Dungeon Master Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 20995 Accepted: 8150 Descr ...
- JAVA基础知识之JVM-——使用反射生成并操作对象
Class对象可以获取类里的方法,由Method对象表示,调用Method的invoke可以执行对应的方法:可以获取构造器,由Constructor对象表示,调用Constructor对象的newIn ...