支持 LINQ 的 Visual Basic 功能

更新:2007 年 11 月

名称“语言集成查询 (LINQ)”是指 Visual Basic 2008 中的新技术,该技术直接在语言中支持查询语法和其他新语言结构。利用 LINQ,您不必学习新语言即可针对外部数据源进行查询。您可以使用 Visual Basic 对关系数据库、XML 存储区或对象中的数据进行查询。由于将查询功能集成到了语言中,因此能够在编译时检查语法错误和类型安全。同时,这种集成还确保您已经了解在 Visual Basic 2008 中编写各种各样丰富的查询所必须了解的知识。

以下各节详尽描述了新的语言结构,以便使您能够开始阅读介绍性文档、代码示例和示例应用程序。您还可以单击链接,以了解有关语言功能如何整合在一起从而实现语言集成查询的更详细说明。演练:在 Visual Basic 中编写查询是一个好的起点。

查询表达式

Visual Basic 2008 中的查询表达式可以采用类似于 SQL 或 XQuery 的声明性语法来表示。在编译时,查询语法转换为对 LINQ 提供程序的标准查询运算符扩展方法实现的方法调用。应用程序通过使用 Imports 语句指定适当的命名空间来控制哪些标准查询运算符位于范围内。Visual Basic 查询表达式的语法如下所示:

Dim londonCusts = From cust In customers _
                  Where cust.City = "London" _
                  Order By cust.Name Ascending _
                  Select cust.Name, cust.Phone

有关更多信息,请参见 Visual Basic 中的 LINQ 简介

隐式类型化变量

不必在声明并初始化变量时显式指定类型,您现在可以使编译器能够推断并分配类型,如以下示例中所示: 这称为“局部类型推理”。

说明:

只有当您在方法体内定义局部变量,并且 Option Infer 设置为 On 时,局部类型推理才能工作。对于 LINQ 中的新项目,On 是默认值。有关更多信息,请参见 Option Infer 语句

' The variable number will be typed as an integer.
Dim aNumber = 5

' The variable name will be typed as a String.
Dim aName = "Virginia"
说明:

在 Visual Basic 2005 及早期版本中,这些示例将会编译,但分配给 aNumber 和 aName 的类型均为 Object。因此,在 Visual Basic 2008 中重新编译并且 Option Infer 设置为 On 的现有项目的行为方式可能与其在早期版本的语言中的行为方式有所不同。

' Query example.
' If numbers is a one-dimensional array of integers, num will be typed
' as an integer and numQuery will be typed as IEnumerable(Of Integer)--
' basically a collection of integers.

Dim numQuery = From num In numbers _
               Where num Mod 2 = 0 _
               Select num

采用这种方式声明的变量是强类型变量,就像您显式指定其类型的变量一样。通过使用局部类型推理,可以创建 LINQ 查询所必需的匿名类型,但它可用于任何局部变量。

有关更多信息,请参见局部类型推理

对象初始值设定项

当您必须创建匿名类型来容纳查询的结果时,将在查询表达式中使用对象初始值设定项。它们还可以用于在查询外部初始化命名类型的对象。使用对象初始值设定项,可以在单独一行中初始化对象,而无需显式调用构造函数。假定有一个名为 Customer 的类,该类具有公共 Name 和 Phone 属性以及其他属性,则可以采用此方式使用对象初始值设定项:

Dim aCust As Customer = New Customer With {.Name = "Mike", _
                                           .Phone = "555-0212"}

有关更多信息,请参见对象初始值设定项:命名类型和匿名类型

匿名类型

利用匿名类型,可以方便地将一组属性临时分组为想要包括在查询结果中的元素。这样,您将能够在查询中按任何顺序选择可用字段的任意组合,而无需为元素定义命名数据类型。

“匿名类型”由编译器动态构建。类型的名称由编译器分配,并且可能随着每次新编译发生更改。因此,不能直接使用该名称。匿名类型采用以下方式初始化:

' Outside a query.
Dim product = New With {.Name = "paperclips", .Price = 1.29}

' Inside a query.
' You can use the existing member names of the selected fields, as was
' shown previously in the Query Expressions section of this topic.
Dim londonCusts1 = From cust In customers _
                   Where cust.City = "London" _
                   Select cust.Name, cust.Phone

' Or you can specify new names for the selected fields.
Dim londonCusts2 = From cust In customers _
                   Where cust.City = "London" _
                   Select CustomerName = cust.Name, _
                   CustomerPhone = cust.Phone

有关更多信息,请参见匿名类型

扩展方法

使用扩展方法,可以从定义外部向数据类型或接口中添加方法。实际上,此功能使您能够将新方法添加到现有类型,而不会实际修改该类型。标准查询运算符本身是一组扩展方法,它们为实现 IEnumerable<T> 的任何类型提供了 LINQ 查询功能。其他 IEnumerable<T> 扩展包括 CountUnionIntersect

以下扩展方法将一个 print 方法添加到 String 类。

' Import System.Runtime.CompilerServices to use the Extension attribute.
<Extension()> _
    Public Sub Print(ByVal str As String)
    Console.WriteLine(str)
End Sub

调用该方法就像调用 String 的普通实例方法一样。

Dim greeting As String = "Hello"
greeting.Print()

有关更多信息,请参见扩展方法 (Visual Basic)

Lambda 表达式

Lambda 表达式是一种无名函数,用于计算并返回单个值。与命名函数不同,Lambda 表达式可以在同时定义和执行。下面的示例显示 4。

Console.WriteLine((Function(num As Integer) num + 1)(3))

可以将 Lambda 表达式定义赋给变量名称,然后使用该名称来调用函数。下面的示例也显示 4。

Dim add1 = Function(num As Integer) num + 1
Console.WriteLine(add1(3))

在 LINQ 中,Lambda 表达式成为许多标准查询运算符的基础。编译器创建 Lambda 表达式以捕获在基础查询方法(比如 Where、Select、Order By、Take While 以及其他方法)中定义的计算。

例如,下面的代码定义一个从学员列表中返回所有高级学员的查询。

Dim seniorsQuery = From stdnt In students _
                   Where stdnt.Year = "Senior" _
                   Select stdnt

查询定义将编译为与下面的示例类似的代码,该示例使用两个 Lambda 表达式为 Where 和 Select 指定参数。

Dim seniorsQuery2 = students _
    .Where(Function(st) st.Year = "Senior") _
    .Select(Function(s) s)

可以使用 For Each 循环运行任一版本:

For Each senior In seniorsQuery
    Console.WriteLine(senior.Last & ", " & senior.First)
Next

有关更多信息,请参见 lambda 表达式

请参见

任务

示例查询 (Visual Basic)

概念

LINQ 和字符串

其他资源

语言集成查询 (LINQ)

Visual Basic 中的 LINQ 入门