LINQ - 概述
世界各地的开发人员一直以来在查询数据方面遇到问题,因为缺乏明确的路径,并且需要掌握多种技术,例如 SQL、Web 服务、XQuery 等。
LINQ(语言集成查询)由 Anders Hejlsberg 设计,在 Visual Studio 2008 中引入,允许即使不了解 SQL、XML 等查询语言也能编写查询。LINQ 查询可以针对多种数据类型编写。
LINQ 查询示例
C#
using System;
using System.Linq;
class Program {
static void Main() {
string[] words = {"hello", "wonderful", "LINQ", "beautiful", "world"};
//Get only short words
var shortWords = from word in words where word.Length <= 5 select word;
//Print each word out
foreach (var word in shortWords) {
Console.WriteLine(word);
}
Console.ReadLine();
}
}
VB
Module Module1
Sub Main()
Dim words As String() = {"hello", "wonderful", "LINQ", "beautiful", "world"}
' Get only short words
Dim shortWords = From word In words _ Where word.Length <= 5 _ Select word
' Print each word out.
For Each word In shortWords
Console.WriteLine(word)
Next
Console.ReadLine()
End Sub
End Module
当编译并执行上述 C# 或 VB 代码时,会产生以下结果:
hello LINQ world
LINQ 的语法
LINQ 有两种语法。如下所示。
Lambda(方法)语法
var longWords = words.Where( w ⇒ w.length > 10); Dim longWords = words.Where(Function(w) w.length > 10)
查询(推导)语法
var longwords = from w in words where w.length > 10; Dim longwords = from w in words where w.length > 10
LINQ 的类型
下面简要介绍 LINQ 的类型。
- LINQ to Objects
- LINQ to XML (XLINQ)
- LINQ to DataSet
- LINQ to SQL (DLINQ)
- LINQ to Entities
除了上述内容外,还有一种名为 PLINQ 的 LINQ 类型,它是微软的并行 LINQ。
.NET 中的 LINQ 架构
LINQ 在 .NET 中采用三层架构,最顶层是语言扩展,底层是数据源,这些数据源通常是实现了 IEnumerable <T> 或 IQueryable <T> 泛型接口的对象。架构如下所示。
查询表达式
查询表达式不过是一个 LINQ 查询,以类似于 SQL 的形式表达,使用 Select、Where 和 OrderBy 等查询运算符。查询表达式通常以关键字“From”开头。
要访问标准 LINQ 查询运算符,默认情况下应导入命名空间 System.Query。这些表达式是在 C# 3.0 的声明性查询语法中编写的。
以下是一个示例,演示完整的查询操作,其中包括数据源创建、查询表达式定义和查询执行。
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Operators {
class LINQQueryExpressions {
static void Main() {
// Specify the data source.
int[] scores = new int[] { 97, 92, 81, 60 };
// Define the query expression.
IEnumerable<int> scoreQuery = from score in scores where score > 80 select score;
// Execute the query.
foreach (int i in scoreQuery) {
Console.Write(i + " ");
}
Console.ReadLine();
}
}
}
当编译并执行上述代码时,会产生以下结果:
97 92 81
扩展方法
扩展方法随 .NET 3.5 引入,仅在静态类中声明,允许将自定义方法添加到对象中,以执行一些精确的查询操作,从而扩展类而无需成为该类的实际成员。这些也可以重载。
简而言之,扩展方法用于将查询表达式转换为传统的调用方法(面向对象)。
LINQ 与存储过程的区别
LINQ 和存储过程之间存在许多差异。这些差异如下所示。
存储过程比 LINQ 查询快得多,因为它们遵循预期的执行计划。
与存储过程相比,执行 LINQ 查询更容易避免运行时错误,因为前者具有 Visual Studio 的 IntelliSense 支持以及编译时的完全类型检查。
LINQ 允许使用 .NET 调试器进行调试,而存储过程则不行。
与存储过程相比,LINQ 支持多个数据库,在存储过程中,必须为不同类型的数据库重写代码。
与部署一组存储过程相比,LINQ 基于解决方案的部署简单易行。
LINQ 的需求
在 LINQ 之前,需要学习 C#、SQL 和各种将两者绑定在一起以形成完整应用程序的 API。由于这些数据源和编程语言存在阻抗不匹配;因此需要简短的编码。
以下是一个示例,说明在 LINQ 出现之前,开发人员在查询数据时使用了多少种不同的技术。
SqlConnection sqlConnection = new SqlConnection(connectString); SqlConnection.Open(); System.Data.SqlClient.SqlCommand sqlCommand = new SqlCommand(); sqlCommand.Connection = sqlConnection; sqlCommand.CommandText = "Select * from Customer"; return sqlCommand.ExecuteReader (CommandBehavior.CloseConnection)
有趣的是,在这些代码行中,只有最后两行定义了查询。使用 LINQ,相同的数据库查询可以用更易读的彩色编码形式编写,如下所示,而且所需时间更短。
Northwind db = new Northwind(@"C:\Data\Northwnd.mdf"); var query = from c in db.Customers select c;
LINQ 的优势
LINQ 提供了许多优势,其中最重要的是其强大的表达能力,使开发人员能够声明性地表达。LINQ 的其他一些优势如下所示。
LINQ 提供语法高亮显示,这有助于在设计时查找错误。
LINQ 提供 IntelliSense,这意味着可以轻松编写更准确的查询。
在 LINQ 中编写代码速度更快,从而大大缩短了开发时间。
由于 LINQ 集成到 C# 语言中,因此可以轻松进行调试。
由于 LINQ 的分层特性,查看两个表之间的关系很容易,这使得能够在更短的时间内组合连接多个表的查询。
LINQ 允许在查询许多不同的数据源时使用单一的 LINQ 语法,这主要是因为其统一的基础。
LINQ 是可扩展的,这意味着可以使用 LINQ 的知识来查询新的数据源类型。
LINQ 提供了在单个查询中连接多个数据源以及将复杂问题分解为易于调试的一组简短查询的功能。
LINQ 提供了一种简单的方法来转换一种数据类型到另一种数据类型,例如将 SQL 数据转换为 XML 数据。