逐步解說:在 Visual Basic 中撰寫查詢

本逐步解說示範如何使用 Visual Basic 語言功能來撰寫 Language-Integrated Query (LINQ) 查詢運算式。 本逐步解說示範如何在學生物件清單上建立查詢、如何執行查詢,以及如何修改查詢。 查詢包含數個功能,包括物件初始設定式、區域型別推斷和匿名型別。

完成本逐步解說之後,則可以開始使用對特定 LINQ 提供者提供您所感興趣的範例和文件。 LINQ 提供者包括 LINQ to SQL、LINQ to DataSet 和 LINQ to XML。

建立專案

若要建立主控台應用程式專案

  1. 啟動 Visual Studio。

  2. [檔案] 功能表上,指向 [開新檔案] ,然後按一下 [專案]

  3. 在 [已安裝的範本]清單中,按一下 [Visual Basic]

  4. 在專案類型清單中,按一下 [主控台應用程式]。 在 [名稱]方塊中輸入專案的名稱,然後按一下 [確定]

    隨即建立專案。 這預設包含 System.Core.dll 的參考。 此外,[專案設計工具,參考頁 (Visual Basic)]上的 [匯入的命名空間]清單包含System.Linq命名空間。

  5. 在 [專案設計工具、編譯頁 (Visual Basic)]上,確定 [選項推斷]設定為 [開啟]

新增記憶體內部資料來源

在本逐步解說中,查詢的資料來源是Student物件的清單。 每個Student物件都包含學生主體中的名字、姓氏、年級和成績排名。

若要新增資料來源

  • 定義 Student 類別,並建立類別的執行個體清單。

    重要

    Student如何:建立項目清單提供定義類別和建立逐步解說範例中使用清單所需的程式碼。 您可以從其中複製這段程式碼,並在您的專案中貼上。 新的程式碼會取代您在建立專案時出現的程式碼。

若要將新的學生新增至學生清單

  • 遵循getStudents方法中的模式,將Student類別的另一個執行個體新增至清單。 新增學生將向您介紹物件初始設定式。 如需詳細資訊,請參閱物件初始設定式:具名和匿名型別

建立查詢

執行時,本節中新增的查詢會產生學生清單,其中的成績排名會將這些學生放在前十名。 因為每次查詢都會選取完整的Student物件,所以查詢結果的型別為IEnumerable(Of Student)。 不過,查詢的型別通常不會在查詢定義中指定。 編譯器反而會使用區域型別推斷來判斷型別。 如需詳細資訊,請參閱區域型別推斷。 查詢的範圍變數currentStudent可作為來源students中每個Student執行個體的參考,提供students中每個物件屬性的存取權。

建立簡單查詢

  1. 在標示為下列項目的方法Main中尋找位置:

    ' ****Paste query and query execution code from the walkthrough,
    ' ****or any code of your own, here in Main.
    

    複製下列程式碼並貼上。

    Dim studentQuery = From currentStudent In students
                       Where currentStudent.Rank <= 10
                       Select currentStudent
    
  2. 將滑鼠指標studentQuery放在程式碼中,以確認編譯器指派的型別為IEnumerable(Of Student)

執行查詢

變數studentQuery包含查詢的定義,並不包含執行查詢的結果。 執行查詢的典型機制是For Each迴圈。 您可透過迴圈反覆運算變數,存取傳回序列中的每個元素。 如需查詢執行的詳細資訊,請參閱撰寫第一個 LINQ 查詢

若要執行查詢

  1. 在專案中的查詢下方新增下列For Each迴圈。

    For Each studentRecord In studentQuery
        Console.WriteLine(studentRecord.Last & ", " & studentRecord.First)
    Next
    
  2. 將滑鼠指標停留在迴圈控制項變數studentRecord上方,以查看其資料類型。 studentRecord的型別推斷為Student,因為studentQuery會傳回Student執行個體的集合。

  3. 按 CTRL+F5 組建並執行應用程式。 請注意主控台視窗中的結果。

修改查詢

如果查詢結果按照指定的順序排列,則會比較容易掃描查詢結果。 您可以根據任何可用的欄位來排序傳回的序列。

若要排序結果

  1. Where陳述式與查詢的Select陳述式之間新增下列Order By子句。 Order By子句會根據每個學生的姓氏,依字母順序從 A 至 Z 排序其結果。

    Order By currentStudent.Last Ascending
    
  2. 若要依姓氏排序,然後依名字排序,請將這兩個欄位新增至查詢:

    Order By currentStudent.Last Ascending, currentStudent.First Ascending
    

    您也可以指定Descending按照從 Z 至 A 的順序排序。

  3. 按 CTRL+F5 組建並執行應用程式。 請注意主控台視窗中的結果。

引入本地識別碼

  1. 新增本節中的程式碼,藉以在查詢運算式中引入本地識別碼。 本機識別碼會保存中繼結果。 在下列範例中,name是識別碼,其中包含學生名字和姓氏的串連。 為了方便起見,可以使用本機識別碼,也可以儲存要計算多次的運算式結果來增強效能。

    Dim studentQuery2 =
            From currentStudent In students
            Let name = currentStudent.Last & ", " & currentStudent.First
            Where currentStudent.Year = "Senior" And currentStudent.Rank <= 10
            Order By name Ascending
            Select currentStudent
    
    ' If you see too many results, comment out the previous
    ' For Each loop.
    For Each studentRecord In studentQuery2
        Console.WriteLine(studentRecord.Last & ", " & studentRecord.First)
    Next
    
  2. 按 CTRL+F5 組建並執行應用程式。 請注意主控台視窗中的結果。

在 Select 子句中加入一個欄位

  1. 從這個區段新增查詢和For Each迴圈,以建立產生序列的查詢,其中的元素與來源中的元素不同。 在下列範例中,來源是物件的集合Student,但只會傳回每個物件的一個成員:姓氏為 Garcia 的學生名字。 因為currentStudent.First是字串,所以studentQuery3傳回的序列所用的資料類型是IEnumerable(Of String),也就是字串序列。 如先前範例所示,studentQuery3的資料類型指派會保留給編譯器使用區域型別推斷來判斷。

    Dim studentQuery3 = From currentStudent In students
                        Where currentStudent.Last = "Garcia"
                        Select currentStudent.First
    
    ' If you see too many results, comment out the previous
    ' For Each loops.
    For Each studentRecord In studentQuery3
        Console.WriteLine(studentRecord)
    Next
    
  2. 將滑鼠指標studentQuery3放在程式碼中,以確認指派的型別是IEnumerable(Of String)

  3. 按 CTRL+F5 組建並執行應用程式。 請注意主控台視窗中的結果。

若要在 Select 子句中建立匿名型別

  1. 從本節新增程式碼,以查看如何在查詢中使用匿名型別。 您想要從資料來源傳回數個欄位,而非完整記錄 (先前範例的currentStudent記錄) 或單一欄位(上一節的First欄位) 時,請使用它們來查詢。 您不必將想包含在結果中欄位所包含在其中新具名的型別下定義,而是直接在Select子句中指定欄位,編譯器即會建立匿名型別,並將這些欄位當做其屬性。 如需詳細資訊,請參閱匿名型別

    下列範例會建立查詢,以傳回成績排名介於 1 至 10 之間的高年級學生姓名與排名。 在此範例中,必須推斷studentQuery4的型別,因為Select子句會傳回匿名型別的執行個體,而該匿名型別無可用的名稱。

    Dim studentQuery4 =
            From currentStudent In students
            Where currentStudent.Year = "Senior" And currentStudent.Rank <= 10
            Order By currentStudent.Rank Ascending
            Select currentStudent.First, currentStudent.Last, currentStudent.Rank
    
    ' If you see too many results, comment out the previous
    ' For Each loops.
    For Each studentRecord In studentQuery4
        Console.WriteLine(studentRecord.Last & ", " & studentRecord.First &
                          ":  " & studentRecord.Rank)
    Next
    
  2. 按 CTRL+F5 組建並執行應用程式。 請注意主控台視窗中的結果。

其他範例

現在您已瞭解基本概念,以下是說明 LINQ 查詢彈性和能力的其他範例清單。 每個範例前面都會有其用途的簡短描述。 將滑鼠指標放在每個查詢的查詢結果變數上方,以查看推斷的型別。 使用For Each迴圈來產生結果。

' Find all students who are seniors.
Dim q1 = From currentStudent In students
         Where currentStudent.Year = "Senior"
         Select currentStudent

' Write a For Each loop to execute the query.
For Each q In q1
    Console.WriteLine(q.First & " " & q.Last)
Next

' Find all students with a first name beginning with "C".
Dim q2 = From currentStudent In students
         Where currentStudent.First.StartsWith("C")
         Select currentStudent

' Find all top ranked seniors (rank < 40).
Dim q3 = From currentStudent In students
         Where currentStudent.Rank < 40 And currentStudent.Year = "Senior"
         Select currentStudent

' Find all seniors with a lower rank than a student who 
' is not a senior.
Dim q4 = From student1 In students, student2 In students
         Where student1.Year = "Senior" And student2.Year <> "Senior" And
               student1.Rank > student2.Rank
         Select student1
         Distinct

' Retrieve the full names of all students, sorted by last name.
Dim q5 = From currentStudent In students
         Order By currentStudent.Last
         Select Name = currentStudent.First & " " & currentStudent.Last

' Determine how many students are ranked in the top 20.
Dim q6 = Aggregate currentStudent In students
         Where currentStudent.Rank <= 20
         Into Count()

' Count the number of different last names in the group of students.
Dim q7 = Aggregate currentStudent In students
         Select currentStudent.Last
         Distinct
         Into Count()

' Create a list box to show the last names of students.
Dim lb As New System.Windows.Forms.ListBox
Dim q8 = From currentStudent In students
         Order By currentStudent.Last
         Select currentStudent.Last Distinct

For Each nextName As String In q8
    lb.Items.Add(nextName)
Next

' Find every process that has a lowercase "h", "l", or "d" in its name.
Dim letters() As String = {"h", "l", "d"}
Dim q9 = From proc In System.Diagnostics.Process.GetProcesses,
         letter In letters
         Where proc.ProcessName.Contains(letter)
         Select proc

For Each proc In q9
    Console.WriteLine(proc.ProcessName & ", " & proc.WorkingSet64)
Next

其他資訊

在您熟悉進行查詢的基本概念之後,即可開始閱讀自己所感興趣的特定類型 LINQ 提供者相關文件和範例:

另請參閱