本主题简要介绍了在 Visual Basic 中 Language-Integrated 查询(LINQ)表达式,以及查询中执行的一些典型作类型。 有关详细信息,请参阅以下主题:
指定数据源 (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"
' ...
可以使用逻辑运算符,例如 And
及 Or
,并且可以在 Where
子句中合并筛选器表达式。 例如,若要仅返回来自伦敦且其名称为 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
,当既不指定Ascending
,也不指定Descending
时。
有关如何在 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
输出为:
年级:高三
塔克,迈克尔
加西亚,雨果
加西亚,黛布拉
塔克, 兰斯
年级:高年级
奥梅尔琴科,斯维特兰纳
奥萨达,米奇科
法科胡里, 法迪
冯,汉英
亚当斯,特里
年:大一
莫滕森,斯文
加西亚,塞萨尔
以下代码中显示的变体对课堂年份进行排序,然后按姓氏对学生每年进行排序。
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 子句。