【发布时间】:2009-01-23 01:15:28
【问题描述】:
什么是 LINQ?我知道它是用于数据库的,但它有什么作用?
【问题讨论】:
-
我相信我已经击败了“无法合理回答”的标准。没有理由关闭这个问题。
-
Listen to the creator of LINQ, Erik Meijer, say what it is. 顺便说一句,它不仅用于数据库。
什么是 LINQ?我知道它是用于数据库的,但它有什么作用?
【问题讨论】:
LINQ 代表语言综合查询。
Microsoft 语言开发人员没有编写 YAQL(另一种查询语言),而是提供了一种直接用他们的语言(例如 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# 团队构建的 DataAccess 技术。它只是工作。
LINQ To Entities - 检查 System.Data.Objects 命名空间。特别注意ObjectContext。这是由 ADO.NET 团队构建的 DataAccess 技术。它比 LINQ To SQL 复杂、强大且更难使用。
LINQ To XML - 检查 System.Xml.Linq 命名空间。从本质上讲,人们对System.Xml 中的内容并不满意。所以微软对其进行了重写,并利用重写的机会引入了一些方法,使使用 LINQ To Objects 处理 XML 变得更加容易。
一些不错的辅助类型,例如Func 和Action。这些类型是具有通用支持的委托。声明自己的自定义(且不可互换)委托类型的日子已经一去不复返了。
以上所有内容都是 .NET Framework 的一部分,可用于任何 .NET 语言(VB.NET、C#、IronPython、COBOL .NET 等)。
好的,关于语言功能。我将坚持使用 C#,因为这是我最了解的。 VB.NET 也有一些类似的改进(还有一些 C# 没有得到的改进——XML 文字)。这是一个简短且不完整的列表。
扩展方法 - 这允许您“添加”一个方法来键入。该方法实际上是一个静态方法,它传递了一个类型的实例,并且仅限于该类型的公共契约,但是对于向您无法控制的类型(字符串)添加方法或添加(完全实现)非常有用) 接口的辅助方法。
Query Comprehension Syntax - 这允许您编写 SQL Like 结构。所有这些东西都被转换为 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);
【讨论】:
LINQ(Language INtegrated Query)可以参考:
一个集合和迭代器操作库,广泛使用高阶函数作为参数 (System.Linq)
一个用于将简单函数作为抽象语法树进行传递和操作的库 (System.Linq.Expressions)
各种语言的语法扩展,为处理集合提供更类似于 SQL 的语法,为匿名函数提供更紧凑的表示法,以及引入在语法上与最终成员函数没有区别的静态辅助函数的机制
数据提供者可能遵守的接口定义,以便接收查询结构并可能对其执行优化,或偶尔兼容的数据提供者本身
这些组件可以单独使用或组合使用。
【讨论】:
简而言之,LINQ(语言集成查询)允许您直接在代码中编写查询。这些查询可以在关系数据库上,也可以在 XML 或内存容器对象上,例如数组和列表。更多信息可在 MSDN 库中找到:http://msdn.microsoft.com/en-us/library/bb308959.aspx
【讨论】:
我将尝试一个简单的答案:LINQ 是一种让您使用类似于 SQL 但可以在 .NET 应用程序中编译的查询语言来查询数据库(或其他数据存储、XML 等)的方法。
【讨论】:
From Where Select, etc. - 即它应该按照结果集实际形成的方式来写
LINQ 代表Language Integrated Query,是一种在 CLR 中提供通用“查询”机制的方法。
在最基本的层面上,这由 IEnumerable
更进一步,LINQ 还定义了一个新的 LINQ 提供程序模型,该模型可以采用表达式树并使用它对 CLR 之外的数据源运行“本机”查询 - 例如,LINQ to SQL、LINQ to XML、LINQ to NHibernate 等。
C# 和 VB.NET 还定义了一种查询语法,允许您在内联编写强类型查询(看起来非常类似于 SQL),然后编译器将其转换为等效的 IEnumerable
对我来说,LINQ 最有趣的地方在于支持它所需的所有 C# 和 VB.NET 特性本身就很有用。扩展方法、匿名类型、lambda 表达式和隐式类型都是支持 LINQ 所必需的——但我们倾向于在纯 LINQ 上下文之外使用这些功能。
[1] 这些是关系术语,函数式程序员可能更喜欢 Map、Reduce、Fold 等。
【讨论】:
LINQ 是一种使用源自 C# 编程语言的习语提取数据的技术。虽然它在功能设计上很大程度上归功于 SQL,但它基本上是它自己的数据查询语言。它在广泛的数据源(SQL 数据库、内存表示、XML 等)中运行。尤其是 LINQ-To-SQL,应该被视为与传统使用嵌入式 SQL 的对比,后者通常被称为 SQL 编程和 C#/VB 编程之间的“阻抗不匹配”。
有关 LINQ 及其局限性的讨论,您可能需要查看以下相关问题:Doesn’t LINQ to SQL miss the point?
【讨论】:
http://msdn.microsoft.com/en-us/netframework/aa904594.aspx
“LINQ 项目是 .NET 框架的一组扩展的代号,其中包含语言集成的查询、设置和转换操作。它使用本机语言语法扩展了 C# 和 Visual Basic,并为充分利用这些功能。”
【讨论】: