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介绍的更多相关文章

  1. LINQ之路 7:子查询、创建策略和数据转换

    在前面的系列中,我们已经讨论了LINQ简单查询的大部分特性,了解了LINQ的支持计术和语法形式.至此,我们应该可以创建出大部分相对简单的LINQ查询.在本篇中,除了对前面的知识做个简单的总结,还会介绍 ...

  2. LINQ之路 4:LINQ方法语法

    书写LINQ查询时又两种语法可供选择:方法语法(Fluent Syntax)和查询语法(Query Expression). LINQ方法语法是非常灵活和重要的,我们在这里将描述使用链接查询运算符的方 ...

  3. LINQ之路(3):LINQ扩展

    本篇文章将从三个方面来进行LINQ扩展的阐述:扩展查询操作符.自定义查询操作符和简单模拟LINQ to SQL. 1.扩展查询操作符 在实际的使用过程中,Enumerable或Queryable中的扩 ...

  4. LINQ之路(2):LINQ to SQL本质

    LINQ之路(2):LINQ to SQL本质 在前面一篇文章中回顾了LINQ基本语法规则,在本文将介绍LINQ to SQL的本质.LINQ to SQL是microsoft针对SQL Server ...

  5. LINQ之路16:LINQ Operators之集合运算符、Zip操作符、转换方法、生成器方法

    本篇将是关于LINQ Operators的最后一篇,包括:集合运算符(Set Operators).Zip操作符.转换方法(Conversion Methods).生成器方法(Generation M ...

  6. LINQ之路15:LINQ Operators之元素运算符、集合方法、量词方法

    本篇继续LINQ Operators的介绍,包括元素运算符/Element Operators.集合方法/Aggregation.量词/Quantifiers Methods.元素运算符从一个sequ ...

  7. LINQ之路10:LINQ to SQL 和 Entity Framework(下)

    在本篇中,我们将接着上一篇“LINQ to SQL 和 Entity Framework(上)”的内容,继续使用LINQ to SQL和Entity Framework来实践“解释查询”,学习这些技术 ...

  8. [转]LINQ之路系列博客导航

    分享一个学习Linq的好博客:Linq之路

  9. LINQ之路系列文章导读

    本系列文章将会分为3篇来进行阐述,如下: LINQ之路(1):LINQ基础 LINQ之路(2):LINQ to SQL本质 LINQ之路(3):LINQ扩展

  10. LINQ之路11:LINQ Operators之过滤(Filtering)

    在本系列博客前面的篇章中,已经对LINQ的作用.C# 3.0为LINQ提供的新特性,还有几种典型的LINQ技术:LINQ to Objects.LINQ to SQL.Entity Framework ...

随机推荐

  1. seo伪原创技术原理分析,php实现伪原创示例

    seo伪原创技术原理分析,php实现伪原创示例 现在seo伪原创一般采用分词引擎以及动态同义词库,模拟百度(baidu),谷歌(google)等中文切词进行伪原创,生成后的伪原创文章更准确更贴近百度和 ...

  2. Hadoop3.0新特性介绍,比Spark快10倍的Hadoop3.0新特性

    Hadoop3.0新特性介绍,比Spark快10倍的Hadoop3.0新特性 Apache hadoop 项目组最新消息,hadoop3.x以后将会调整方案架构,将Mapreduce 基于内存+io+ ...

  3. Backup: Numbers in Perl6

    Perl6 is a new language, not a improved version of Perl5. Perl6 inherits many good features from man ...

  4. oracle 数据泵 详解

    导出数据 1)按用户导 expdp scott/tiger@orcl schemas=scott dumpfile=expdp.dmp DIRECTORY=dir logfile=expdp.log ...

  5. UserSelector兼容

    1.更新到asp.net2.0或以上,将Microsoft.Web.UI.TreeView更换为新的System.Web.UI.WebControls.TreeView 2.将UserId,UserT ...

  6. 坑爹的VS2012

    2.2.2.如果卸载 Visual Studio 2010 Service Pack 1,则必须先重新安装 Visual Studio 2010,然后才能再次安装 SP1 如果卸载 Visual St ...

  7. 【jQuery UI 1.8 The User Interface Library for jQuery】.学习笔记.9.Progressbar控件

    Progressbar控件用来显示任意进程的完成百分比. 默认安装启用 配置选项 控件暴露的事件API progressbar暴露的独一无二的方法 一些现实生活的例子 当前版本中,我们或系统必须明确进 ...

  8. linux 下某个文字在某几行的shell 写法 。

    cat -n  139.sql |grep "kkkn"  sed -n '697804,697812p' 139.sql

  9. DBLINK的session无法关闭,报异常!

    ------解决方法-------------------------------------------------------- --ALTER SESSION alter session clo ...

  10. HDU 3076:ssworld VS DDD(概率DP)

    http://acm.split.hdu.edu.cn/showproblem.php?pid=3076 ssworld VS DDD Problem Description   One day, s ...