本主题简要介绍了在 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 ClassDim 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 子句。