Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Le variabili usate nelle operazioni di query LINQ (Language-Integrated Query) sono fortemente tipate e devono essere compatibili tra loro. La tipizzazione forte viene usata nell'origine dati, nella query stessa e nell'esecuzione della query. La figura seguente identifica i termini usati per descrivere una query LINQ. Per altre informazioni sulle parti di una query, vedere Operazioni di query di base (Visual Basic).
Il tipo della variabile di intervallo nella query deve essere compatibile con il tipo degli elementi nell'origine dati. Il tipo della variabile di query deve essere compatibile con l'elemento sequenza definito nella Select clausola . Infine, il tipo degli elementi della sequenza deve essere compatibile anche con il tipo della variabile di controllo ciclo usata nell'istruzione For Each che esegue la query. Questa digitazione avanzata facilita l'identificazione degli errori di tipo in fase di compilazione.
Visual Basic semplifica la digitazione implementando l'inferenza del tipo locale, nota anche come tipizzazione implicita. Questa funzionalità viene usata nell'esempio precedente e verrà usata in tutti gli esempi e la documentazione di LINQ. In Visual Basic, l'inferenza del tipo locale viene eseguita semplicemente usando un'istruzione Dim senza una As clausola . Nell'esempio seguente, city è fortemente tipizzato come stringa.
Dim city = "Seattle"
Annotazioni
L'inferenza del tipo locale funziona solo quando Option Infer è impostata su On. Per altre informazioni, vedere Istruzione Option Infer.
Tuttavia, anche se si usa l'inferenza del tipo locale in una query, le stesse relazioni di tipo sono presenti tra le variabili nell'origine dati, la variabile di query e il ciclo di esecuzione della query. È utile avere una conoscenza di base di queste relazioni tra tipi quando si scrivono query LINQ o si consultano gli esempi e il codice nella documentazione.
Potrebbe essere necessario specificare un tipo esplicito per una variabile di intervallo che non corrisponde al tipo restituito dall'origine dati. È possibile specificare il tipo della variabile di intervallo usando una As clausola . Tuttavia, viene generato un errore se la conversione è una conversione verso un tipo di dati più piccolo e Option Strict è impostato su On. È pertanto consigliabile eseguire la conversione sui valori recuperati dall'origine dati. È possibile convertire i valori dall'origine dati al tipo di variabile di intervallo esplicito usando il Cast metodo . È anche possibile fare il cast dei valori selezionati nella clausola Select a un tipo esplicito che sia diverso dal tipo della variabile di intervallo. Questi punti sono illustrati nel codice seguente.
Dim numbers1() As Integer = {1, 2, 4, 16, 32, 64}
Dim numbers2() As Double = {5.0#, 10.0#, 15.0#}
' This code does not result in an error.
Dim numberQuery1 = From n As Integer In numbers1 Where n > 5
' This code results in an error with Option Strict set to On. The type Double
' cannot be implicitly cast as type Integer.
Dim numberQuery2 = From n As Integer In numbers2 Where n > 5
' This code casts the values in the data source to type Integer. The type of
' the range variable is Integer.
Dim numberQuery3 = From n In numbers2.Cast(Of Integer)() Where n > 5
' This code returns the value of the range variable converted to Integer. The type of
' the range variable is Double.
Dim numberQuery4 = From n In numbers2 Where n > 5 Select CInt(n)
Query che restituiscono interi elementi dei dati di origine
Nell'esempio seguente viene illustrata un'operazione di query LINQ che restituisce una sequenza di elementi selezionati dai dati di origine. L'origine, names, contiene una matrice di stringhe e l'output della query è una sequenza contenente stringhe che iniziano con la lettera M.
Dim names = {"John", "Rick", "Maggie", "Mary"}
Dim mNames = From name In names
Where name.IndexOf("M") = 0
Select name
For Each nm In mNames
Console.WriteLine(nm)
Next
Equivale al codice seguente, ma è molto più breve e più facile da scrivere. La preferenza per l'inferenza dei tipi locali nelle query è lo stile preferito in Visual Basic.
Dim names2 = {"John", "Rick", "Maggie", "Mary"}
Dim mNames2 As IEnumerable(Of String) =
From name As String In names
Where name.IndexOf("M") = 0
Select name
For Each nm As String In mNames
Console.WriteLine(nm)
Next
Le relazioni seguenti esistono in entrambi gli esempi di codice precedenti, indipendentemente dal fatto che i tipi vengano determinati in modo implicito o esplicito.
Il tipo degli elementi nell'origine dati,
names, è il tipo della variabile di intervallo,name, nella query.Il tipo dell'oggetto selezionato,
name, determina il tipo della variabile di query,mNames. Ecconameuna stringa, quindi la variabile di query è IEnumerable(Of String) in Visual Basic.La query definita in
mNamesviene eseguita nelFor Eachciclo . Il ciclo itera sui risultati dell'esecuzione della query. PoichémNames, quando viene eseguito, restituirà una sequenza di stringhe, la variabile di iterazione del ciclo, ,nmè anche una stringa.
Query che restituiscono un campo dagli elementi selezionati
Nell'esempio seguente viene illustrata un'operazione di query LINQ to SQL che restituisce una sequenza contenente una sola parte di ogni elemento selezionato dall'origine dati. La query accetta una raccolta di Customer oggetti come origine dati e proietta solo la Name proprietà nel risultato. Poiché il nome del cliente è una stringa, la query produce una sequenza di stringhe come output.
' Method GetTable returns a table of Customer objects.
Dim customers = db.GetTable(Of Customer)()
Dim custNames = From cust In customers
Where cust.City = "London"
Select cust.Name
For Each custName In custNames
Console.WriteLine(custName)
Next
Le relazioni tra le variabili sono simili a quelle dell'esempio più semplice.
Il tipo degli elementi nell'origine dati,
customers, è il tipo della variabile di intervallo,cust, nella query. In questo esempio, il tipo èCustomer.L'istruzione
Selectrestituisce laNameproprietà di ogniCustomeroggetto anziché l'intero oggetto. PoichéNameè una stringa, la variabile di query,custNames, sarà nuovamente IEnumerable(Of String), non diCustomer.Poiché
custNamesrappresenta una sequenza di stringhe, laFor Eachvariabile di iterazione del ciclo,custName, deve essere una stringa.
Senza inferenza del tipo locale, l'esempio precedente sarebbe più complesso da scrivere e comprendere, come illustrato nell'esempio seguente.
' Method GetTable returns a table of Customer objects.
Dim customers As Table(Of Customer) = db.GetTable(Of Customer)()
Dim custNames As IEnumerable(Of String) =
From cust As Customer In customers
Where cust.City = "London"
Select cust.Name
For Each custName As String In custNames
Console.WriteLine(custName)
Next
Query che richiedono tipi anonimi
L'esempio seguente mostra una situazione più complessa. Nell'esempio precedente era poco pratico specificare i tipi per tutte le variabili in modo esplicito. In questo esempio, è impossibile. Anziché selezionare interi Customer elementi dall'origine dati o un singolo campo da ogni elemento, la Select clausola in questa query restituisce due proprietà dell'oggetto originale Customer : Name e City. In risposta alla Select clausola , il compilatore definisce un tipo anonimo che contiene queste due proprietà. Il risultato dell'esecuzione nameCityQuery nel For Each ciclo è una raccolta di istanze del nuovo tipo anonimo. Poiché il tipo anonimo non ha un nome utilizzabile, non è possibile specificare il tipo di nameCityQuery o custInfo in modo esplicito. Ovvero, con un tipo anonimo, non si dispone di alcun nome di tipo da usare al posto di String in IEnumerable(Of String). Per altre informazioni, vedere Tipi anonimi.
' Method GetTable returns a table of Customer objects.
Dim customers = db.GetTable(Of Customer)()
Dim nameCityQuery = From cust In customers
Where cust.City = "London"
Select cust.Name, cust.City
For Each custInfo In nameCityQuery
Console.WriteLine(custInfo.Name)
Next
Anche se non è possibile specificare tipi per tutte le variabili nell'esempio precedente, le relazioni rimangono invariate.
Il tipo degli elementi nell'origine dati è di nuovo il tipo della variabile di intervallo nella query. In questo esempio,
custè un'istanza diCustomer.Poiché l'istruzione
Selectproduce un tipo anonimo, la variabile di query,nameCityQuery, deve essere tipizzata in modo implicito come tipo anonimo. Un tipo anonimo non ha un nome utilizzabile e pertanto non può essere specificato in modo esplicito.Il tipo della variabile di iterazione nel
For Eachciclo è il tipo anonimo creato nel passaggio 2. Poiché il tipo non ha un nome utilizzabile, il tipo della variabile di iterazione del ciclo deve essere determinato in modo implicito.