Procedura dettagliata: Scrittura delle query in Visual Basic

Questa procedura dettagliata dimostra come usare le funzionalità del linguaggio Visual Basic per scrivere espressioni di query LINQ (Language Integrated Query). La procedura dettagliata illustra come creare query in un elenco di oggetti Student, come eseguire le query e come modificarle. Le query incorporano diverse funzionalità, tra cui inizializzatori di oggetti, inferenza del tipo di variabile locale e tipi anonimi.

Dopo aver completato questa procedura dettagliata, si sarà pronti a passare agli esempi e alla documentazione per il provider LINQ specifico a cui si è interessati. I provider LINQ includono LINQ to SQL, LINQ to DataSet e LINQ to XML.

Creare un progetto

Per creare un progetto di applicazione console

  1. Avviare Visual Studio.

  2. Scegliere Nuovo dal menu Filee quindi fare clic su Progetto.

  3. Nell'elenco Modelli installati fare clic su Visual Basic.

  4. Dall'elenco dei tipi di progetto scegliere Applicazione console. Nella casella Nome digitare un nome per il progetto e quindi fare clic su OK.

    Viene creato un progetto. Per impostazione predefinita, contiene un riferimento a System.Core.dll. Inoltre, l'elenco Spazi dei nomi importati nella pagina Riferimenti, Creazione progetti (Visual Basic) include lo spazio dei nomi System.Linq.

  5. Nella pagina Compilazione, Creazione progetti (Visual Basic) assicurarsi che la voce Option Infer sia impostata su On.

Aggiungere un'origine dati in memoria

L'origine dati per le query di questa procedura dettagliata è un elenco di oggetti Student. Ogni oggetto Student contiene un nome, un cognome, un anno di corso e una classificazione accademica nel corpo dello studente.

Per aggiungere l'origine dati

  • Definire una classe Student e creare un elenco di istanze della classe.

    Importante

    Il codice necessario per definire la classe Student e creare l'elenco usato negli esempi di procedura dettagliata viene fornito in Procedura: Creare un elenco di elementi. È possibile copiarlo da lì e incollarlo nel progetto. Il nuovo codice sostituisce il codice visualizzato al momento della creazione del progetto.

Per aggiungere un nuovo studente all'elenco

  • Seguire il criterio nel metodo getStudents per aggiungere un'altra istanza della classe Student all'elenco. L'aggiunta dello studente introdurrà gli inizializzatori di oggetti. Per altre informazioni, vedere Inizializzatori di oggetti: tipi denominati e anonimi.

Creare una query

Quando viene eseguita, la query aggiunta in questa sezione genera un elenco degli studenti la cui classificazione accademica li colloca tra i primi dieci. Poiché la query seleziona l'oggetto Student completo ogni volta, il tipo del risultato della query è IEnumerable(Of Student). Tuttavia, il tipo della query in genere non viene specificato nelle definizioni di query. Il compilatore usa invece l'inferenza del tipo di variabile locale per determinare il tipo. Per altre informazioni, vedere Inferenza del tipo di variabile locale. La variabile di intervallo della query, currentStudent, funge da riferimento a ogni istanza di Student nell'origine, students, fornendo l'accesso alle proprietà di ogni oggetto in students.

Per creare una query semplice

  1. Trovare la posizione nel metodo Main del progetto contrassegnata come segue:

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

    Copiare il codice seguente e incollarlo.

    Dim studentQuery = From currentStudent In students
                       Where currentStudent.Rank <= 10
                       Select currentStudent
    
  2. Posizionare il puntatore del mouse su studentQuery nel codice per verificare che il tipo assegnato dal compilatore sia IEnumerable(Of Student).

Eseguire la query

La variabile studentQuery contiene la definizione della query, non i risultati della relativa esecuzione. Un meccanismo tipico per l'esecuzione di una query è un ciclo For Each. A ogni elemento della sequenza restituita si accede tramite la variabile di iterazione nel ciclo. Per altre informazioni sull'esecuzione di query, vedere Scrittura della prima query LINQ.

Per eseguire la query

  1. Aggiungere il ciclo For Each seguente sotto la query nel progetto.

    For Each studentRecord In studentQuery
        Console.WriteLine(studentRecord.Last & ", " & studentRecord.First)
    Next
    
  2. Posizionare il puntatore del mouse sulla variabile di controllo del ciclo studentRecord per visualizzarne il tipo di dati. Il tipo di studentRecord viene dedotto come Student, perché studentQuery restituisce una raccolta di istanze di Student.

  3. Compilare ed eseguire l'applicazione premendo CTRL+F5. Notare i risultati nella finestra della console.

Modificare la query

È più semplice analizzare i risultati delle query se sono disposti in un ordine specificato. È possibile ordinare la sequenza restituita in base a qualsiasi campo disponibile.

Per ordinare i risultati

  1. Aggiungere la clausola Order By seguente tra l'istruzione Where e l'istruzione Select della query. La clausola Order By ordinerà i risultati alfabeticamente da A a Z, in base al cognome di ogni studente.

    Order By currentStudent.Last Ascending
    
  2. Per ordinare in base al cognome e quindi al nome, aggiungere entrambi i campi alla query:

    Order By currentStudent.Last Ascending, currentStudent.First Ascending
    

    È anche possibile specificare Descending per ordinare da Z a A.

  3. Compilare ed eseguire l'applicazione premendo CTRL+F5. Notare i risultati nella finestra della console.

Per introdurre un identificatore locale

  1. Aggiungere il codice in questa sezione per introdurre un identificatore locale nell'espressione di query. L'identificatore locale conterrà un risultato intermedio. Nell'esempio seguente name è un identificatore che contiene una concatenazione dei nomi e dei cognomi degli studenti. Un identificatore locale può essere usato per praticità oppure per migliorare le prestazioni archiviando i risultati di un'espressione che altrimenti verrebbe calcolata più volte.

    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. Compilare ed eseguire l'applicazione premendo CTRL+F5. Notare i risultati nella finestra della console.

Per proiettare un campo nella clausola Select

  1. Aggiungere la query e il ciclo For Each di questa sezione per creare una query che produce una sequenza i cui elementi differiscono da quelli nell'origine. Nell'esempio seguente l'origine è una raccolta di oggetti Student, ma viene restituito un solo membro di ogni oggetto, ovvero il nome degli studenti il cui cognome è Garcia. Poiché currentStudent.First è una stringa, il tipo di dati della sequenza restituita da studentQuery3 è IEnumerable(Of String), una sequenza di stringhe. Come negli esempi precedenti, l'assegnazione di un tipo di dati per studentQuery3 viene lasciata da determinare al compilatore usando l'inferenza del tipo di variabile locale.

    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. Posizionare il puntatore del mouse su studentQuery3 nel codice per verificare che il tipo assegnato sia IEnumerable(Of String).

  3. Compilare ed eseguire l'applicazione premendo CTRL+F5. Notare i risultati nella finestra della console.

Per creare un tipo anonimo nella clausola Select

  1. Aggiungere il codice di questa sezione per vedere come vengono usati i tipi anonimi nelle query. Tali tipi vengono usati nelle query quando si vuole che vengano restituiti diversi campi dall'origine dati invece di record completi (record currentStudent negli esempi precedenti) o singoli campi (First nella sezione precedente). Invece di definire un nuovo tipo denominato contenente i campi da includere nel risultato, si specificano i campi nella clausola Select e il compilatore crea un tipo anonimo con tali campi come proprietà. Per altre informazioni, vedere Tipi anonimi.

    L'esempio seguente crea una query che restituisce il nome e la classificazione degli studenti senior la cui classificazione accademica è compresa tra 1 e 10, nell'ordine di tale classificazione. In questo esempio, il tipo di studentQuery4 deve essere dedotto perché la clausola Select restituisce un'istanza di un tipo anonimo, che non ha un nome utilizzabile.

    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. Compilare ed eseguire l'applicazione premendo CTRL+F5. Notare i risultati nella finestra della console.

Esempi aggiuntivi

Dopo aver compreso le nozioni di base, di seguito è riportato un elenco di esempi aggiuntivi per illustrare la flessibilità e le potenzialità delle query LINQ. Ogni esempio è preceduto da una breve descrizione delle operazioni che esegue. Posizionare il puntatore del mouse sulla variabile dei risultati di ogni query per visualizzare il tipo dedotto. Usare un ciclo For Each per produrre i risultati.

' 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

Informazioni aggiuntive

Dopo aver acquisito familiarità con i fondamenti dell'uso delle query, è possibile leggere la documentazione e vedere gli esempi per il tipo specifico di provider LINQ a cui si è interessati:

Vedi anche