关于.net:什么是LINQ?

What is LINQ exactly?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Learning about LINQ

大家好,

我只想知道linq在dotnet中到底是什么?它是如何工作的?

德克萨斯州


Linq有很多东西,它是许多小东西的组合。

我很抱歉,这个答案将是一堆乱七八糟的信息。你最好等一下,看看是否有人能更好地总结它,然后用谷歌搜索我使用的关键词。

Linq代表"语言集成查询",最幼稚的解释是他们在C语言中添加了类似SQL的语法。

因此,而不是:

1
IEnumerable<int> values = otherValues.Where(i => i > 5);

它们的语法如下:

1
2
3
IEnumerable<int> values = from i in otherValues
                          where i > 5
                          select i;

C编译器实际上会将上面的第二段代码转换为第一段代码,所以实际上,您只是在集合中调用方法。

然而,这是谜题的另一部分。这些方法实际上根本没有在集合中定义。它们被定义为扩展方法,这意味着它们是在其他地方定义的,一些技巧基本上是说"让程序员使用这些方法,就好像它们是在集合类型中定义的一样,并在编译期间修复代码"。

所以上面的第一段代码是:

1
IEnumerable<int> values = otherValues.Where(i => i > 5);

最终被编译为:

1
IEnumerable<int> values = Enumerable.Where(otherValues, i => i > 5);

此处定义的Where方法:Enumerable.Where。

下一个神奇之处是C编译器不使用可枚举的。它所做的是,它只是动态地重写代码,使其看起来像我答案中的第二段代码,并让正常的类型推断解决它。换言之,它将假装您实际上编写了第二段代码,然后看到"OtherValues"是一个List,其中T是一个int,然后发现Enumerable.Where是要调用的代码。

这意味着,对于集合以外的其他类型,实际上可以自己实现where,而linq语法将不再明智。

这意味着…可以查询那些不是真正在内存中的集合。例如,如果上面的"OtherValues"知道如何从数据库中获取数据,那么将调用不同的Where方法,而不是Enumerable.Where中的方法。

这允许其他实现以自己的方式完成它们的工作,例如,为您编写SQL,执行它,并打包结果,以便它看起来像是从内存中的集合开始的调用代码。

下一个魔法是表达。上面的where方法的参数i => i > 5在大多数情况下是lambda表达式或匿名方法,您可以像这样为内存中的集合声明它:

1
2
Func<int, bool> w = delegate(int i) { return i > 5; };
IEnumerable<int> values = otherValues.Where(w);

但是,C中的表达式支持意味着您也可以将其声明为:

1
Expression<Func<int, bool>> w = i => i > 5;

在这里,编译器并不是将它实际存储为编译后的代码块,而是一个内存中的数据结构,它知道它需要一个参数,将它与5进行比较,然后返回结果。请注意,您必须使用lambda方法来编写它,而不是作为委托。

这种知识允许那些其他的where实现(如果声明它们接受表达式)不仅获得"where子句"的控制权,而且可以查看它、将它分离并重写它。

这意味着可以在知道如何处理SQL代码的where方法中生成SQL。

下面是where方法的linq-to-sql声明:queryly.where。

因此,linq是添加到c编译器中的许多较小技术的组合:

  • LINQ语法
  • 扩展方法
  • LINQ扩展方法(+其他实现,特别是查看LINQ to SQL。)
  • lambda表达式和表达式树。


msdn在介绍Linq方面做得很好:

[...]

.NET Language-Integrated Query defines
a set of general purpose standard
query operators that allow traversal,
filter, and projection operations to
be expressed in a direct yet
declarative way in any .NET-based
programming language. The standard
query operators allow queries to be
applied to any IEnumerable-based
information source. LINQ allows third
parties to augment the set of standard
query operators with new
domain-specific operators that are
appropriate for the target domain or
technology. More importantly, third
parties are also free to replace the
standard query operators with their
own implementations that provide
additional services such as remote
evaluation, query translation,
optimization, and so on. By adhering
to the conventions of the LINQ
pattern, such implementations enjoy
the same language integration and tool
support as the standard query
operators.

[...]

http://msdn.microsoft.com/library/bb308959.aspx


这是几个不同的事情。

在System.Linq命名空间中,Linq是一组扩展方法,允许您直接在代码中查询集合。它是"语言集成查询"的缩写。

它也是一组提供程序,允许您查询不同的数据源—SQL with Linq to SQL、XML with Linq to XML等等。


Linq是IEnumerable的到的一组扩展方法。它的目的是让您抽象出从集合中获取对象的一些细节。当您通过LINQ"查询"您的集合时,您以一种声明性的方式进行查询,而不是命令式的方式。这意味着你的LINQ查询显示了你想要得到什么,而不是你想要得到什么。在foreach()循环中,必须非常明确地说明如何筛选、分组和排序结果。对于Linq,它只是一些简短的语句,实现细节是从您这里抽象出来的。

很多人错误地认为它与SQL有关,因为Linq to SQL,但实际上这只是Linq的一小部分。你不必使用L2S来充分利用Linq的功能,事实上很多人不需要。尽管在我个人看来,如果你是一家.NET商店,只有SQL Server作为你的数据库,那么Linq to SQL就是一个好消息。


把它看作是使用类似SQL的语法查询对象。以下是从http://msdn.microsoft.com/en-us/vcsharp/aa336746.aspx复制的示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void Linq1()
{
    int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

    var lowNums =
        from n in numbers
        where n < 5
        select n;

    Console.WriteLine("Numbers < 5:");
    foreach (var x in lowNums)
    {
        Console.WriteLine(x);
    }
}