基本查询操作 (Visual Basic)Basic Query Operations (Visual Basic)

本主题简要介绍了 Visual Basic 中的 语言集成查询 (LINQ)Language-Integrated Query (LINQ) 表达式,以及在查询中执行的一些典型操作。This topic provides a brief introduction to 语言集成查询 (LINQ)Language-Integrated Query (LINQ) expressions in Visual Basic, and to some of the typical kinds of operations that you perform in a query. 有关更多信息,请参见下列主题:For more information, see the following topics:

Visual Basic 中的 LINQ 简介Introduction to LINQ in Visual Basic

查询Queries

演练:在 Visual Basic 中编写查询Walkthrough: Writing Queries in Visual Basic

指定数据源(从)Specifying the Data Source (From)

LINQLINQ 查询中,第一步是指定要查询的数据源。In a LINQLINQ query, the first step is to specify the data source that you want to query. 因此,查询中的 From 子句始终是第一个。Therefore, the From clause in a query always comes first. 查询运算符根据源的类型选择并生成结果。Query operators select and shape the result based on the type of the source.

Dim query = From cust In customers
'           ...

From 子句指定数据源、customers范围变量cust)。The From clause specifies the data source, customers, and a range variable, cust. 范围变量类似于循环迭代变量,但在查询表达式中,不会发生实际迭代。The range variable is like a loop iteration variable, except that in a query expression, no actual iteration occurs. 当执行查询时,通常使用 For Each 循环,范围变量充当对 customers中每个后续元素的引用。When the query is executed, often by using a For Each loop, the range variable serves as a reference to each successive element in customers. 由于编译器可以推断 cust 的类型,因此无需显式指定它。Because the compiler can infer the type of cust, you do not have to specify it explicitly. 有关用和编写的查询的示例,但没有显式类型化,请参阅查询操作中的类型关系(Visual Basic)For examples of queries written with and without explicit typing, see Type Relationships in Query Operations (Visual Basic).

有关如何在 Visual Basic 中使用 From 子句的详细信息,请参阅From 子句For more information about how to use the From clause in Visual Basic, see From Clause.

筛选数据(位置)Filtering Data (Where)

可能最常见的查询操作是以布尔表达式的形式应用筛选器。Probably the most common query operation is applying a filter in the form of a Boolean expression. 然后,查询仅返回表达式为 true 的元素。The query then returns only those elements for which the expression is true. Where 子句用于执行筛选。A Where clause is used to perform the filtering. 筛选器指定数据源中要包括在结果序列中的元素。The filter specifies which elements in the data source to include in the resulting sequence. 在下面的示例中,只包括具有伦敦地址的客户。In the following example, only those customers who have an address in London are included.

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

可以使用逻辑运算符(如 AndOr)在 Where 子句中合并筛选表达式。You can use logical operators such as And and Or to combine filter expressions in a Where clause. 例如,若要仅返回来自伦敦并且其名称为 Devon 的客户,请使用以下代码:For example, to return only those customers who are from London and whose name is Devon, use the following code:

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

若要返回伦敦或巴黎的客户,请使用以下代码:To return customers from London or Paris, use the following code:

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

有关如何在 Visual Basic 中使用 Where 子句的详细信息,请参阅Where 子句For more information about how to use the Where clause in Visual Basic, see Where Clause.

数据排序(排序方式)Ordering Data (Order By)

将返回的数据按特定顺序排序通常是非常方便的。It often is convenient to sort returned data into a particular order. Order By 子句将导致返回序列中的元素按指定的一个或多个字段进行排序。The Order By clause will cause the elements in the returned sequence to be sorted on a specified field or fields. 例如,下面的查询根据 Name 属性对结果进行排序。For example, the following query sorts the results based on the Name property. 由于 Name 是一个字符串,因此返回的数据将按字母顺序从 A 到 Z 排序。Because Name is a string, the returned data will be sorted alphabetically, from A to Z.

Dim londonCusts1 = From cust In customers
                   Where cust.City = "London"
                   Order By cust.Name Ascending
'                   ...

要对结果进行从 Z 到 A 的逆序排序,请使用 Order By...Descending 子句。To order the results in reverse order, from Z to A, use the Order By...Descending clause. 如果 AscendingDescending 均未指定,则默认值为 AscendingThe default is Ascending when neither Ascending nor Descending is specified.

有关如何在 Visual Basic 中使用 Order By 子句的详细信息,请参阅Order By 子句For more information about how to use the Order By clause in Visual Basic, see Order By Clause.

选择数据(选择)Selecting Data (Select)

Select 子句指定返回元素的形式和内容。The Select clause specifies the form and content of returned elements. 例如,您可以指定您的结果是由完整的 Customer 对象组成,只包括一个 Customer 属性、属性的子集、来自各种数据源的属性的组合,还是基于计算的某些新的结果类型。For example, you can specify whether your results will consist of complete Customer objects, just one Customer property, a subset of properties, a combination of properties from various data sources, or some new result type based on a computation. Select 子句生成除源元素副本以外的内容时,该操作称为投影。When the Select clause produces something other than a copy of the source element, the operation is called a projection.

若要检索由完整的 Customer 对象组成的集合,请选择范围变量本身:To retrieve a collection that consists of complete Customer objects, select the range variable itself:

Dim londonCusts2 = From cust In customers
                   Where cust.City = "London"
                   Order By cust.Name Ascending
                   Select cust

如果 Customer 实例是具有多个字段的大型对象,并且要检索的所有字段都是名称,则可以选择 "cust.Name",如下面的示例中所示。If a Customer instance is a large object that has many fields, and all that you want to retrieve is the name, you can select cust.Name, as shown in the following example. 局部类型推理可识别这会将结果类型从 Customer 的对象集合更改为字符串的集合。Local type inference recognizes that this changes the result type from a collection of Customer objects to a collection of strings.

Dim londonCusts3 = From cust In customers
                   Where cust.City = "London"
                   Order By cust.Name Ascending
                   Select cust.Name

若要从数据源中选择多个字段,您有两种选择:To select multiple fields from the data source, you have two choices:

  • Select 子句中,指定要包含在结果中的字段。In the Select clause, specify the fields you want to include in the result. 编译器将定义一个匿名类型,该类型将这些字段作为其属性。The compiler will define an anonymous type that has those fields as its properties. 有关详细信息,请参阅匿名类型For more information, see Anonymous Types.

    由于以下示例中返回的元素是匿名类型的实例,因此不能在代码中的其他位置以名称引用该类型。Because the returned elements in the following example are instances of an anonymous type, you cannot refer to the type by name elsewhere in your code. 该类型的编译器指定名称包含在正常 Visual Basic 代码中无效的字符。The compiler-designated name for the type contains characters that are not valid in normal Visual Basic code. 在下面的示例中,londonCusts4 中的查询所返回的集合中的元素是匿名类型的实例In the following example, the elements in the collection that is returned by the query in londonCusts4 are instances of an anonymous type

    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
    

    - 或 --or-

  • 定义包含要包含在结果中的特定字段的命名类型,并在 Select 子句中创建和初始化该类型的实例。Define a named type that contains the particular fields that you want to include in the result, and create and initialize instances of the type in the Select clause. 仅在以下情况下使用此选项:必须在返回的集合之外使用各个结果,或者必须在方法调用中将它们作为参数传递。Use this option only if you have to use individual results outside the collection in which they are returned, or if you have to pass them as parameters in method calls. 以下示例中 londonCusts5 的类型为 IEnumerable (of NamePhone)。The type of londonCusts5 in the following example is 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 子句For more information about how to use the Select clause in Visual Basic, see Select Clause.

联接数据(联接和分组联接)Joining Data (Join and Group Join)

可以通过多种方式在 From 子句中组合多个数据源。You can combine more than one data source in the From clause in several ways. 例如,以下代码使用两个数据源,并在结果中隐式组合这两个数据源的属性。For example, the following code uses two data sources and implicitly combines properties from both of them in the result. 查询选择姓氏以元音开头的学生。The query selects students whose last names start with a vowel.

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

备注

您可以使用在如何:创建项列表中创建的学生列表运行此代码。You can run this code with the list of students created in How to: Create a List of Items.

Join 关键字等效于 SQL 中的 INNER JOINThe Join keyword is equivalent to an INNER JOIN in SQL. 它基于两个集合中的元素之间的匹配键值合并两个集合。It combines two collections based on matching key values between elements in the two collections. 查询返回所有或部分具有匹配键值的集合元素。The query returns all or part of the collection elements that have matching key values. 例如,以下代码将复制上一个隐式联接的操作。For example, the following code duplicates the action of the previous implicit 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 一样。Group Join combines collections into a single hierarchical collection, just like a LEFT JOIN in SQL. 有关详细信息,请参阅Join 子句Group Join 子句For more information, see Join Clause and Group Join Clause.

数据分组(Group By)Grouping Data (Group By)

您可以添加一个 Group By 子句,以便根据元素的一个或多个字段对查询结果中的元素进行分组。You can add a Group By clause to group the elements in a query result according to one or more fields of the elements. 例如,下面的代码按课程年份对学生进行分组。For example, the following code groups students 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 语句的输出为:If you run this code using the list of students created in How to: Create a List of Items, the output from the For Each statement is:

Year:初级Year: Junior

Tucker、MichaelTucker, Michael

Garcia、HugoGarcia, Hugo

Garcia、DebraGarcia, Debra

Tucker、LanceTucker, Lance

Year:高级Year: Senior

Omelchenko, SvetlanaOmelchenko, Svetlana

Osada、MichikoOsada, Michiko

Fakhouri, FadiFakhouri, Fadi

Feng、冯汉英 (Feng, Hanying

Adams,TerryAdams, Terry

Year: FreshmanYear: Freshman

Mortensen, SvenMortensen, Sven

Garcia、CesarGarcia, Cesar

以下代码中显示的变体对类年进行排序,然后按姓氏对每年内的学生进行排序。The variation shown in the following code orders the class years, and then orders the students within each year by last name.

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 子句For more information about Group By, see Group By Clause.

另请参阅See also