-
LINQ,语言集成查询(Language Integrated Query)是一组用于
c#和
Visual Basic语言的扩展。它容许编写C#或者Visual Basic代码以查询数据库相同的方式操做内存数据。
-
中文名
-
语言集成查询
-
外文名
-
Language Integrated Query
-
开发公司
-
微软
-
语 言
-
C#,Visual Basic
从技术角度而言,LINQ定义了大约40个查询操做符,如select、from、in、where以及order by(
C#中)。使用这些操做符能够编写查询语句。不过,这些查询还能够基于不少类型的数据,每一个数据类型都须要一个单独的LINQ类型。
通过了最近 20 年,
面向对象
编程技术( object-oriented (OO) programming technologies )在工业领域的应用已经进入了一个稳定的发展阶段。程序员如今都已经认同像 类(classes)、对象(objects)、方法(methods)这样的语言特性。考察如今和下一代的技术,一个新的编程技术的重大挑战开始呈现出来,即
面向对象技术诞生以来并无解决下降访问和整合信息数据( accessing and integrating information )的复杂度的问题。其中两个最主要访问的数据源与数据库(
database)和
XML(
标准通用标记语言下的一个应用)相关。
LINQ 提供了一条更常规的途径即给
.Net Framework添加一些能够应用于全部信息源( all sources of information )的具备多种用途( general-purpose )的语法查询特性( query facilities ),这是比向开发语言和运行时( runtime )添加一些关系数据( relational )特性或者相似 XML 特性( XML-specific )更好的方式。这些语法特性就叫作 .NET Language Integrated Query (LINQ) 。
包含 DLinq 和 XLinq。
-
LINQ的读法:(1)lin k (2)lin q
-
LINQ的全称:Language-Integrated Query
-
LINQ的关键词:from, select, in, where, group by, orderby, …
-
LINQ的写法:
1) from 临时变量 in 实现IEnumerable<T>接口的对象
[orderby 条件]
[group by 条件]
select 临时变量中被查询的值
2) 实现IEnumerable<T>接口的对象.LINQ方法名(lambda表达式)。如:
string input = "hello world";
int count = input.Count(w=>w == 'o'); //查询字母o出现的次数
注意:可以使用LINQ的对象须要实现IEnumerable<T>接口。而且LINQ的查询
表达式是在最近一次建立对 象时才被编译的。
5. 命名空间(.NET Framework):System.Linq;
注意:Linq是在.NET Framework 3.5 中出现的技术,因此在建立新项目的时候必需要选3.5或者更高版 本,不然没法使用。选择3.5或更高版本的
.NET Framework以后,建立类文件中会自动包含System.Linq 的命名空间。
C#3.0 LINQ 查询语法
首先来看一个很简单的LINQ查询例子,查询一个int
数组中小于5的数字,并按照大小顺序排列:
static void Main(string[] args)
{
int[] arr = new int[] { 8, 5, 89, 41, 1, 2, 3, 65, 1 };
var m = from n in arr where n < 5 orderby n descending select n;//小于5,而且倒叙排列显示
foreach (var n in m)
{
Console.WriteLine(n);
}
Console.ReadLine();
}
上述代码除了LINQ查询语法外,其余都是咱们所熟悉的语法,而LINQ查询语法跟SQL查询语法很类似,除了前后顺序。
Q:为什么 LINQ 查询语法是以 from 关键字开头的,而不是以 select 关键字开头的?select 开头这种写法跟SQL的写法更接近,更易懂呀?
A:简单来讲,为了IDE的智能感知(Intellisence)这个功能,select 关键字放在后面了。
编程语言以 select 开头写LINQ查询语法不是没出现过,你若是使用过2005年的VB9 CTP 版本,那时候VB9的LINQ查询语法就是 select 关键字在前面,可是 select 关键字在前面,在作智能感知(Intelisence)时候就很头大。通过微软IDE组的权衡,肯定了把 from 关键字放在最前面。
那时候 VB9 LINQ的查询语法仍是 select 参数在最前面。不事后来 VB9 测试版改为了跟 C# 同样的作法, from 关键字放在最前面了。
更详细的解释,来自装配脑壳
假设你要书写这样的代码:Select p. Name, p.Age From p In persons Where xxx ,代码是一个个字符输入的。
咱们在写到 p in persons 以前,p 的类型是没法推测的,因此写 Select p. 的时候,Name之类的属性不会弹出智能提示来。
这样就须要先去写 From 这句,再回来写 Select。
微软IDE组通过反复考虑决定,还不如就把 Select 写到后面了。因而编程语言中的写法就肯定这样来写了。
VB9 的这个变化能够参看这篇博客:
Select/From vs. From/Select revisited...
咱们再来看一个稍稍复杂的LINQ查询:
在咱们列举的语言字符串中,咱们但愿按照字符长短,分类列举出来,实现代码以下:
static void Main(string[] args)
{
string[] languages = { "Java", "C#", "C++", "Delphi", "VB.net", "VC.net", "C++Builder", "Kylix", "Perl", "Python" };
var query = from item in languages
group item by item.Length into lengthGroups
orderby lengthGroups.Key
select lengthGroups;
foreach (var item in query)
{
Console.WriteLine("strings of length{0}", item.Key);
foreach (var val in item)
{
Console.WriteLine(val);
}
}
Console.ReadLine();
}
其中的 into 关键字表示 将前一个查询的结果视为后续查询的生成器,这里是跟 group by 一块儿使用的。
LINQ中的Group by不要跟 SQL 中的Group by 混淆,
SQL因为是二维结构,Group by 的一些逻辑受二维结构的约束,没法像 LINQ 中的Group by 这么灵活。
事实上,LINQ的查询语法存在如下两种形式:
查询方法方式:(Methord Syntax)
主要利用System.Linq.Enumerable类中定义的扩展方法和Lambda表达式方式进行查询
查询语句方式:(Query Syntax)一种更接近SQL语法的查询方式,可读性更好。
LINQ(Language Integrated Query)是Visual Studio 2008中的领军人物。借助于LINQ技术,咱们可使用一种相似SQL的语法来查询任何形式的数据。目前为止LINQ所支持的
数据源有
SQL Server、
Oracle、
XML(
标准通用标记语言下的一个应用)以及内存中的数据集合。开发人员也可使用其提供的扩展框架添加更多的数据源,例如MySQL、Amazon甚至是
GoogleDesktop。
通常来说,这类查询语句的一个重要特色就是能够并行化执行。虽然有些状况下并行可能会带来一些问题,但这种状况很是少见。这样也就水到渠成地引出了PLINQ这个
并行处理的LINQ类库。
PLINQ原名为Parallel LINQ,支持XML和内存中的数据集合。执行于远程服务器上的查询语句(例如LINQ to SQL)显然没法实现这个功能。
将LINQ语句转换为PLINQ语句极为简单——只须要在查询语句中From子句所指定的数据源的最后添加.AsParallel()便可。随后Where、OrderBy和Select子句将自动改成调用这个并行的LINQ版本。
据MSDN Magazine介绍,PLINQ能够以三种方式执行。第一种是管道处理:一个线程用来读取数据源,而其余的线程则用来处理查询语句,两者同步进行——虽然这个单一的消费线程可能并不那么容易与多个生产
线程同步。不过如果可以仔细配置好负载平衡的话,仍然会极大地减小内存占用。
第二种模式叫作“stop and go”,用于处理
结果集须要被一次返回时(例如调用ToList、ToArray或对结果排序)的状况。在这种模式下,将依次完成各个处理过程,并将结果统一返回给消费线程。这个模式在性能上将优于第一种模式,由于它省去了用来保持线程同步所花费的开销。
最后一种方法叫作“inverted enumeration”。该方法并不须要实现收集到全部的输出,而后在单一的线程中处理,而是将最终调用的函数经过ForAll扩展传递到每一个线程中。这是目前为止最快的一种处理模式,不过这须要传递到ForAll中的函数是
线程安全的,且最好不包含任何lock之类的互斥语句。
如果PLINQ中任意的一个线程
抛出异常,那么全部的其余线程将会被终止。如果抛出了多个异常,那么这些异常将被组合成一个MultipleFailuresException类型的异常,但每一个异常的调用
堆栈仍会被保留。
一、无需复杂学习过程便可上手
二、编写更少代码便可建立完整应用。
三、更快开发错误更少的应用程序。
五、可以大幅减小过程控制语句的代码块,使代码的可读性和可维护性大幅提升。
六、任何对象或数据源均可以定制实现Linq
适配器,为数据交互带来真正方便。
支持如下公共语言运行时 (
CLR) 方法和属性,由于它们能够在查询表达式中进行转换以包含在
OData服务的请求 URI 中:
String成员 |
支持的 OData 函数 |
Concat
|
string concat(string p0, string p1)
|
Contains
|
bool substringof(string p0, string p1)
|
EndsWith
|
bool endswith(string p0, string p1)
|
IndexOf
|
int indexof(string p0, string p1)
|
Length
|
int length(string p0)
|
Replace
|
string replace(string p0, string find, string replace)
|
Substring
|
string substring(string p0, int pos)
|
Substring
|
string substring(string p0, int pos, int length)
|
ToLower
|
string tolower(string p0)
|
ToUpper
|
string toupper(string p0)
|
Trim
|
string trim(string p0)
|
DateTime成员1 |
支持的 OData 函数 |
Day
|
int day(DateTime p0)
|
Hour
|
int hour(DateTime p0)
|
Minute
|
int minute(DateTime p0)
|
Month
|
int month(DateTime p0)
|
Second
|
int second(DateTime p0)
|
Year
|
int year(DateTime p0)
|
1也支持
Visual Basic中等效的Microsoft.VisualBasic.DateAndTime的日期和时间属性以及DatePart方法。
Math成员 |
支持的 OData 函数 |
Ceiling
|
decimal ceiling(decimal p0)
|
Ceiling
|
double ceiling(double p0)
|
Floor
|
decimal floor(decimal p0)
|
Floor
|
double floor(double p0)
|
Round
|
decimal round(decimal p0)
|
Round
|
double round(double p0)
|
Expression成员 |
支持的 OData 函数 |
TypeIs
|
bool isof(type p0)
|
客户端或许还能够在客户端上计算其余 CLR 函数。对于没法在客户端上计算以及没法转换为有效请求URI以便在服务器上计算的任何表达式,将引起NotSupportedException。