LINQ是什么?它有什么作用?

140

LINQ是什么?我知道它与数据库有关,但它具体做什么呢?


26
我相信我已经击败了“无法合理回答”的标准。这个问题没有理由被关闭。 - Amy B
3
请听LINQ的创造者Erik Meijer解释什么是LINQ。顺便提一下,它不仅仅用于数据库。 - Sнаđошƒаӽ
7个回答

182

LINQ代表“语言集成查询”。

微软的语言开发人员提供了一种直接在它们的语言中(如C#和Visual Basic)表达查询的方式,而不是编写一个新的查询语言。形成这些查询的技术不依赖于被查询的实现细节,因此您可以针对许多目标(数据库、内存对象、XML等)编写有效的查询,几乎不考虑查询将以何种方式执行的底层方式。

让我们从属于.NET Framework(3.5)的组件开始探索。

  • LINQ To Objects - 检查System.Linq.Enumerable的查询方法。这些方法针对IEnumerable<T>,允许以类型安全的方式查询任何已编译的.NET方法,而不是表达式。

  • LINQ To Anything - 检查System.Linq.Queryable的一些查询方法。这些方法针对IQueryable<T>,允许构建可由底层实现翻译的表达式树。

  • 表达式树 - 检查System.Linq.Expressions命名空间。这是代表代码的数据。实际上,您应该了解这些内容,但不需要直接使用这些类型编写代码。语言特性(如lambda表达式)可以允许您使用各种简写来避免直接处理这些类型。

  • LINQ To SQL - 查看System.Data.Linq命名空间,并特别注意DataContext。这是由C#团队构建的数据访问技术,使用起来非常简单。

  • LINQ To Entities - 查看System.Data.Objects命名空间,并特别注意ObjectContext。这是由ADO.NET团队构建的数据访问技术,功能复杂、强大,但使用起来比LINQ To SQL更为困难。

  • LINQ To XML - 查看System.Xml.Linq命名空间。本质上,人们对System.Xml中的内容不满意。因此,微软进行了重新编写并利用这次重写引入了一些使得使用LINQ To Objects操作XML更加容易的方法。

  • 一些很好的帮助类型,例如FuncAction。这些类型是具有泛型支持的委托。不用再声明自己的自定义委托类型了。

  • 以上所有内容都是.NET Framework的一部分,可从任何.NET语言(如VB.NET、C#、IronPython、COBOL .NET等)中使用。


    好的,接下来是语言特性。我将专注于C#,因为这是我最熟悉的语言。VB.NET也有几个类似的改进(以及一些C#没有获得的——XML文字)。以下是一个简短而不完整的列表。

    • 扩展方法 - 这允许您"添加"一个方法到类型中。该方法实际上是一个静态方法,它接收一个类型的实例,并且受限于类型的公共契约,但它非常适用于向您无法控制的类型(例如字符串)添加自定义方法,或者向接口添加(完全实现的)帮助方法。

    • 查询推导语法 - 这允许您以类似SQL的结构编写查询语句。所有这些内容都会转换为System.Linq.Queryable或System.Linq.Enumerable上的方法(取决于myCustomers的类型)。这是完全可选的,即使不使用它,也可以很好地使用LINQ。这种查询声明样式的一个优点是范围变量已经被作用域化:它们不需要在每个子句中重新声明。

    • IEnumerable<string> result =
       from c in myCustomers
       where c.Name.StartsWith("B")
       select c.Name;
      
    • Lambda表达式 - 这是指定方法的简写方式。C#编译器将其转换为匿名方法或真正的System.Linq.Expressions.Expression。您需要真正理解它们才能很好地使用LINQ。它由三个部分组成:参数列表、箭头和方法体。

    • IEnumerable<string> result = myCustomers
       .Where(c => c.Name.StartsWith("B"))
       .Select(c => c.Name);`
      
    • 匿名类型 - 有时编译器具备足够的信息来为你创建一个类型。这些类型并不是真正的匿名类型:编译器在创建它们时会给它们命名。但是这些名称是在编译时生成的,开发者不能在设计时使用那个名称。

    • myCustomers.Select(c => new 
      {
        Name = c.Name;
        Age = c.Age;
      })
      
    • 隐式类型 - 有时编译器根据初始化的信息就能够为你推断出变量的类型。你可以使用 var 关键字来让编译器自动进行推断。在声明匿名类型的变量时,必须使用隐式类型,因为程序员无法使用 匿名 类型的名称。

    • // The compiler will determine that names is an IEnumerable<string>
      var names = myCustomers.Select(c => c.Name);
      

    16

    LINQ(Language INtegrated Query)可能指:

    • 用于集合和迭代器操作的库,广泛使用高阶函数作为参数(System.Linq)

    • 用于传递和操作简单函数的抽象语法树的库(System.Linq.Expressions)

    • 各种语言的语法扩展,提供更类似SQL的语法来处理集合,更紧凑的匿名函数符号表示法,以及通过语法无法区分的静态帮助函数引入机制。

    • 接口定义,数据提供程序可以符合该定义以接收查询结构,并可能对其进行优化。有时也指兼容的数据提供程序本身。

    这些组件可以单独使用或组合使用。


    13
    简而言之,LINQ(语言集成查询)允许您直接在代码中编写查询。这些查询可以针对关系数据库,也可以针对XML或内存容器对象,例如数组和列表。更多信息可在MSDN库中找到:http://msdn.microsoft.com/en-us/library/bb308959.aspx

    10
    我尝试用简单的语言解释:LINQ是一种查询数据库(或其他数据存储、XML等)的方式,使用类似于SQL但可以在.NET应用程序中编译的查询语言。

    1
    那么,Linq和SQL之间到底有什么区别? - Kredns
    我认为这个术语可能有更复杂的称呼,但是它们的结构不同: SQL 是 Select From Where,而 LINQ 则是 From Where Select。使用 LINQ 循环更容易。LINQ 更容易 :), 且由其生成的 SQL 通常已经足够好,考虑到时间节省。 - jcollum
    2
    说实话,有人可以争论SQL应该写成From Where Select等形式 - 也就是应该按照实际形成结果集的方式来编写。 - Don Cheadle

    7
    LINQ代表语言集成查询,是在CLR中提供通用“查询”机制的一种方式。
    最基本的级别是,在IEnumerable<T>上定义了一组方法,例如Select、Sum、Where等,可用于限制、投影等[1]。
    更进一步,LINQ还定义了一个新的LINQ提供程序模型,可以接受表达式树并使用它来运行针对CLR之外的数据源的“本地”查询,例如LINQ to SQL、LINQ to XML、LINQ to NHibernate等。
    C#和VB.NET还定义了一种查询语法,允许您编写内联的强类型查询(看起来非常类似于SQL),然后编译器将其转换为相应的IEnumerable<T>调用。
    对我而言,LINQ最有趣的事情是,支持它所需的所有C#和VB.NET特性在其自身范围内都很有用。扩展方法、匿名类型、Lambda表达式和隐式类型都需要支持LINQ,但我们倾向于在纯LINQ上下文之外使用这些特性。

    [1] 这些是关系型术语,函数式编程者可能更喜欢Map、Reduce、Fold等。


    7
    LINQ是一种利用源自C#编程语言的习惯用语提取数据的技术。虽然它在功能设计上借鉴了SQL,但它本质上是自己的数据查询语言。它可以操作广泛的数据源(SQL数据库、内存表示、XML等)。特别是LINQ-To-SQL应该被视为与传统嵌入式SQL的使用形成对比,后者经常遭受所谓的“阻抗不匹配”问题,即SQL编程和C#/VB编程之间的不匹配。
    关于LINQ及其限制的讨论,您可能想看看这个相关问题:Doesn’t LINQ to SQL miss the point?

    0

    那么这是用于数据库吗?根据我在 Stack Overflow 上看到的,它更像是针对 .net 环境中的集合。 - OscarRyz

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接