基本查询操作 (Visual Basic)
本主题简要介绍 Visual Basic 中的语言集成查询 (LINQ) 表达式,以及您在查询中执行的一些典型类型的运算。 有关更多信息,请参见下列主题:
指定数据源 (From)
在 LINQ 查询中,第一步是指定要查询的数据源。 因此,查询中的 From 子句总是最先出现。查询运算符选择、用于根据源的类型的结果。
Dim query = From cust In customers
' ...
From 子句指定数据源 customers 和范围变量 cust。 范围变量类似于循环迭代变量,但在查询表达式中,实际上不发生迭代。 执行查询(通常使用 For Each 循环执行)时,范围变量将用作对 customers 中的每个后续元素的引用。 因为编译器可以推断 cust 的类型,所以您不必显式指定此类型。 有关使用和不使用显式指定的类型编写的查询示例,请参见查询操作中的类型关系 (Visual Basic)。
有关如何在 Visual Basic 中使用 From 子句的更多信息,请参见 From 子句 (Visual Basic)。
筛选数据 (Where)
也许最常用的查询操作是应用布尔表达式形式的筛选器。 因此,这种查询只返回那些表达式结果为 true 的元素。 Where 子句用于执行筛选。 筛选器指定要在结果序列中包含数据源中的哪些元素。 在下面的示例中,只包含那些地址位于伦敦的客户。
Dim londonCusts = From cust In customers
Where cust.City = "London"
' ...
您可以使用逻辑运算符(如 And 和 Or)将筛选器表达式组合在 Where 子句中。 例如,若要只返回位于伦敦并且姓名为 Devon 的客户,请使用下面的代码:
Where cust.City = "London" And cust.Name = "Devon"
若要返回位于伦敦或巴黎的客户,请使用下面的代码:
Where cust.City = "London" Or cust.City = "Paris"
有关如何在 Visual Basic 中使用 Where 子句的更多信息,请参见 Where 子句 (Visual Basic)。
对数据进行排序 (Order By)
将返回的数据按特定的顺序排列通常会带来方便。 Order By 子句将使所返回序列中的元素按指定的一个或多个字段排序。 例如,下面的查询基于 Name 属性对结果排序。 由于 Name 是一个字符串,因此返回的数据将按字母 A 到 Z 的顺序排序。
Dim londonCusts1 = From cust In customers
Where cust.City = "London"
Order By cust.Name Ascending
' ...
若要按相反顺序(从 Z 到 A)对结果排序,请使用 Order By...Descending 子句。 如果 Ascending 和 Descending 都未指定,则默认为 Ascending。
有关如何在 Visual Basic 中使用 Order By 子句的更多信息,请参见 Order By 子句 (Visual Basic)。
选择数据 (Select)
Select 子句指定所返回元素的形式和内容。 例如,您可以指定结果包含的是整个 Customer 对象、仅一个 Customer 属性、属性的子集、来自不同数据源的属性的组合,还是一些基于计算的新结果类型。 当 Select 子句生成除源元素副本以外的内容时,该操作称为“投影”。
若要检索包含整个 Customer 对象的集合,请选择范围变量本身:
Dim londonCusts2 = From cust In customers
Where cust.City = "London"
Order By cust.Name Ascending
Select cust
如果 Customer 实例是一个包含许多字段的大型对象,而您要检索的只是名称,则可以选择 cust.Name,如下面的示例所示。 局部类型推理知道此操作会将结果类型从 Customer 对象集合更改为字符串集合。
Dim londonCusts3 = From cust In customers
Where cust.City = "London"
Order By cust.Name Ascending
Select cust.Name
若要从数据源中选择多个字段,您可以使用两种方法:
在 Select 子句中,指定要包含在结果中的字段。 编译器将定义一个匿名类型,该类型将这些字段作为其属性。 有关更多信息,请参见匿名类型 (Visual Basic)。
由于下面示例中的返回元素是匿名类型的实例,因此您无法在代码中的其他位置按名称引用该类型。 编译器为该类型指定的名称含有在普通 Visual Basic 代码中无效的字符。 在下面的示例中,londonCusts4 内的查询返回的集合中的元素是某个匿名类型的实例
Dim londonCusts4 = From cust In customers Where cust.City = "London" Order By cust.Name Ascending Select Name = cust.Name, Phone = cust.Phone For Each londonCust In londonCusts4 Console.WriteLine(londonCust.Name & " " & londonCust.Phone) Next
- 或 -
定义含有您要包括在结果中的特定字段的命名类型,并在 Select 子句中创建和初始化该类型的实例。 仅当您必须在返回各个结果的集合以外使用这些结果,或者必须将这些结果作为参数传入方法调用时,才使用此选项。 下面的示例中的 londonCusts5 类型是 IEnumerable(Of NamePhone)。
Public Class NamePhone Public Name As String Public Phone As String ' Additional class elements End Class
Dim londonCusts5 = From cust In customers Where cust.City = "London" Order By cust.Name Ascending Select New NamePhone With {.Name = cust.Name, .Phone = cust.Phone}
有关如何在 Visual Basic 中使用 Select 子句的更多信息,请参见 Select 子句 (Visual Basic)。
联接数据(Join 和 Group Join)
您可以使用多种方法将多个数据源组合到 From 子句中。 例如,下面的代码使用两个数据源并将来自这二者的属性隐式组合在结果中。 该查询选择姓氏以元音开头的学生。
Dim vowels() As String = {"A", "E", "I", "O", "U"}
Dim vowelNames = From student In students, vowel In vowels
Where student.Last.IndexOf(vowel) = 0
Select Name = student.First & " " &
student.Last, Initial = vowel
Order By Initial
For Each vName In vowelNames
Console.WriteLine(vName.Initial & ": " & vName.Name)
Next
备注
您可以使用如何:创建项列表中创建的学生列表运行此代码。
Join 关键字等效于 SQL 中的 INNER JOIN。 它基于两个集合中的元素之间的匹配键值对这两个集合进行组合。 该查询返回包含这些匹配键值的全部或部分集合元素。 例如,下面的代码复制上面的隐式联接操作。
Dim vowelNames2 = From student In students
Join vowel In vowels
On student.Last(0) Equals vowel
Select Name = student.First & " " &
student.Last, Initial = vowel
Order By Initial
Group Join 将多个集合组合为单个分层集合,就像 SQL 中的 LEFT JOIN。 有关更多信息,请参见Join 子句 (Visual Basic)和Group Join 子句 (Visual Basic)。
对数据进行分组 (Group By)
您可以添加 Group By 子句,以根据元素的一个或多个字段对查询结果中的元素进行分组。 例如,下面的代码按年级 (class year) 对学生进行分组。
Dim studentsByYear = From student In students
Select student
Group By year = student.Year
Into Classes = Group
For Each yearGroup In studentsByYear
Console.WriteLine(vbCrLf & "Year: " & yearGroup.year)
For Each student In yearGroup.Classes
Console.WriteLine(" " & student.Last & ", " & student.First)
Next
Next
如果您使用如何:创建项列表中创建的学生列表运行此代码,则 For Each 语句将输出:
Year: Junior
Tucker, Michael
Garcia, Hugo
Garcia, Debra
Tucker, Lance
Year: Senior
Omelchenko, Svetlana
Osada, Michiko
Fakhouri, Fadi
Feng, Hanying
Adams, Terry
Year: Freshman
Mortensen, Sven
Garcia, Cesar
下面显示的代码变体对年级排序,然后对每个年级的学生按姓氏排序。
Dim studentsByYear2 = From student In students
Select student
Order By student.Year, student.Last
Group By year = student.Year
Into Classes = Group
有关Group By的更多信息,请参见Group By 子句 (Visual Basic)。