基本查询操作 (Visual Basic)

本主题简要介绍 Visual Basic 中的语言集成查询 (LINQ) 表达式,以及在查询中执行的一些典型操作。 有关详细信息,请参阅下列主题:

Visual Basic 中的 LINQ 简介

查询

演练:用 Visual Basic 编写查询

指定数据源 (From)

在 LINQ 查询中,第一步是指定要查询的数据源。 因此,查询中的 From 子句始终第一个出现。 查询运算符根据源的类型选择和调整结果。

Dim query = From cust In customers
'           ...

From 子句指定数据源 customers 和范围变量 cust。 范围变量类似于循环迭代变量,只不过在查询表达式中不会真正发生迭代。 执行查询(通常使用 For Each 循环)时,范围变量用作对 customers 中每个连续元素的引用。 由于编译器可以推断 cust 的类型,因此无需显式指定它。 有关使用和不使用显式类型化编写的查询示例,请参阅查询操作中的类型关系 (Visual Basic)

有关如何在 Visual Basic 中使用 From 子句的详细信息,请参阅 From 子句

筛选数据 (Where)

或许,最常见的查询操作是以布尔表达式的形式应用筛选器。 然后,查询仅返回表达式为 true 的元素。 Where 子句用于执行筛选。 筛选器指定数据源中的哪些元素要包含在生成的序列中。 在以下示例中,仅包含地址位于伦敦的客户。

Dim londonCusts = From cust In customers
                  Where cust.City = "London"
'                 ...

可以在 Where 子句中使用 AndOr 等逻辑运算符来组合筛选表达式。 例如,若要仅返回来自伦敦且名称为 Devon 的客户,请使用以下代码:

Where cust.City = "London" And cust.Name = "Devon"

若要返回来自伦敦或巴黎的客户,请使用以下代码:

Where cust.City = "London" Or cust.City = "Paris"

有关如何在 Visual Basic 中使用 Where 子句的详细信息,请参阅 Where 子句

对数据排序 (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 子句

选择数据 (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 代码中无效的字符。 在以下示例中,由 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 子句

联接数据(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 子句Group Join 子句

对数据分组 (Group By)

可以添加 Group By 子句,根据元素的一个或多个字段对查询结果中的元素进行分组。 例如,以下代码按年级对学生进行分组。

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 子句

另请参阅