Share via


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

更新:2007 年 11 月

本逐步解說將引導您認識全新的 Visual Basic 2008 語言功能,並示範如何使用這些功能來撰寫 Language-Integrated Query (LINQ) 查詢運算式。其中會示範如何在 Student 物件清單上建立查詢、如何執行這些查詢,以及如何加以修改。這些查詢加入了 Visual Basic 2008 的幾項新功能,包括物件初始設定式、區域型別推斷和匿名型別。

當您完成本逐步解說之後,便可繼續參閱您想了解的特定 LINQ 提供者 (Provider) 的範例和文件。LINQ 提供者包括 LINQ to SQL、LINQ to DataSet 和 LINQ to XML。

視訊的連結 如需觀看示範影片,請參閱影片 HOW TO:在 Visual Basic 中撰寫查詢

建立專案

若要建立 .NET Framework 3.5 (含) 以後版本的專案

  1. 啟動 Visual Studio 2008。

  2. 在 [檔案] 功能表上,按一下 [新增專案]。

  3. 按一下 [主控台應用程式],然後按一下 [確定]。

    專案隨即建立。此專案預設包含 System.Core.dll 的參考,以及 System.Linq 命名空間 (Namespace) 的 Imports 陳述式 (Statement),這兩項都是執行 LINQ 查詢時所需的項目。

加入記憶體中資料來源

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

若要加入資料來源

  • 定義 Student 類別 (Class),並建立這個類別的執行個體 (Instance) 清單。

    重要事項:

    HOW TO:建立項目清單提供了定義 Student 類別和建立這個逐步解說範例所用清單時所需的程式碼。您可以將該處的複製程式碼複製並貼上至專案中。新的程式碼會取代在建立專案時出現的程式碼。

若要將新的學生加入至學生清單

  • 依照 getStudents 方法中的模式,將另一個 Student 類別執行個體加入至清單。在加入學生時,會引入物件初始設定式,而這是 Visual Basic 2008 的新功能。如需詳細資訊,請參閱物件初始設定式:具名和匿名型別

建立查詢

執行本節加入的查詢時,會產生學術排名在前十名的學生的清單。因為查詢每次都會選取完整的 Student 物件,所以查詢結果的型別是 IEnumerable(Of Student)。不過,在查詢定義中通常不會指定查詢型別。相反地,編譯器 (Compiler) 會使用區域型別推斷來判斷型別。如需詳細資訊,請參閱區域型別推斷。查詢的範圍變數 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 迴圈 (Loop)。在傳回的序列中,每個項目都是透過迴圈的反覆運算變數進行存取。如需查詢執行的詳細資訊,請參閱撰寫第一個 LINQ 查詢 (Visual Basic)

若要執行查詢

  1. 在專案的查詢下方加入下列 For Each 迴圈。

    For Each studentRecord In studentQuery
        Console.WriteLine(studentRecord.Last & ", " & studentRecord.First)
    Next
    
  2. 將滑鼠指標放在迴圈的控制項變數 studentRecord 上,以查看其資料型別。因為 studentQuery 會傳回 Student 執行個體的集合,所以 studentRecord 的型別會推斷為 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. 加入本節中的程式碼,以查看如何在查詢中使用匿名型別。匿名型別是 Visual Basic 2008 的新功能。當您想要傳回資料來源中的數個欄位,而不是完整記錄 (上一個範例中的 currentStudent 記錄) 或單一欄位 (上一節中的 First),就可以在查詢中使用匿名型別。您可以在 Select 子句中指定欄位,讓編譯器建立匿名型別並使用這些欄位做為該型別的屬性。如需詳細資訊,請參閱匿名型別

    下列範例建立的查詢會傳回學術排名在 1 與 10 之間的高年級生的姓名和排名,依學術排名進行排序。在這個範例中,因為 Select 子句會傳回匿名型別的執行個體,而匿名型別是沒有名稱的,所以必須推斷 studentQuery4 的型別。

    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 提供者類型的文件和範例:

LINQ to Objects

LINQ to SQL

LINQ to XML

LINQ to DataSet

請參閱

工作

範例查詢 (Visual Basic)

概念

其他 LINQ 資源

區域型別推斷

物件初始設定式:具名和匿名型別

匿名型別

Visual Basic 中的 LINQ 簡介

其他資源

Language-Integrated Query (LINQ)

使用 Visual Basic 撰寫 LINQ 入門

Visual Basic 中的 LINQ

查詢 (Visual Basic)