In questo esempio viene illustrato come unire dati da origini diverse in una sequenza di tipi nuovi.
Nota
Non provare a creare un join di dati in memoria o nel file system con dati che sono ancora in un database. Questi join tra domini possono generare risultati non definiti a causa dei diversi modi in cui vengono definite le operazioni di join per le query di database e per altri tipi di origini. È anche possibile che tale operazione possa generare un'eccezione di memoria insufficiente se la quantità di dati nel database è piuttosto grande. Per creare un join di dati di un database con i dati in memoria, chiamare prima ToList
o ToArray
nella query di database e quindi creare il join nella raccolta restituita.
Per creare il file di dati
Nell'esempio seguente viene illustrato come usare un tipo denominato Student
per archiviare i dati uniti da due raccolte di stringhe in memoria che simulano i dati del foglio di calcolo in formato CSV. La prima raccolta di stringhe rappresenta i nomi e gli ID degli studenti e la seconda raccolta rappresenta gli ID degli studenti, nella prima colonna, e i punteggi di quattro esami. L'ID viene usato come chiave esterna.
Imports System.Collections.Generic
Imports System.Linq
Class Student
Public FirstName As String
Public LastName As String
Public ID As Integer
Public ExamScores As List(Of Integer)
End Class
Class PopulateCollection
Shared Sub Main()
Dim names As String() = System.IO.File.ReadAllLines("../../../names.csv")
Dim scores As String() = System.IO.File.ReadAllLines("../../../scores.csv")
Dim queryNamesScores = From nameLine In names
Let splitName = nameLine.Split(New Char() {","})
From scoreLine In scores
Let splitScoreLine = scoreLine.Split(New Char() {","})
Where Convert.ToInt32(splitName(2)) = Convert.ToInt32(splitScoreLine(0))
Select New Student() With {
.FirstName = splitName(1), .LastName = splitName(0), .ID = splitName(2),
.ExamScores = (From scoreAsText In splitScoreLine Skip 1
Select Convert.ToInt32(scoreAsText)).ToList()}
Dim students As List(Of Student) = queryNamesScores.ToList()
For Each s In students
Console.WriteLine("The average score of " & s.FirstName & " " &
s.LastName & " is " & s.ExamScores.Average())
Next
Console.WriteLine("Press any key to exit.")
Console.ReadKey()
End Sub
End Class
Nella clausola Seleziona clausola viene usato un inizializzatore di oggetto per creare un'istanza di ogni nuovo oggetto Student
con i dati delle due origini.
Se non è necessario archiviare i risultati della query, può essere più utile usare i tipi anonimi rispetto ai tipi denominati. I tipi denominati sono necessari se si passano i risultati della query al di fuori del metodo in cui viene eseguita la query. Nell'esempio seguente viene eseguita la stessa attività dell'esempio precedente, ma vengono usati i tipi anonimi anziché i tipi denominati:
Dim queryNamesScores2 =
From nameLine In names
Let splitName = nameLine.Split(New Char() {","})
From scoreLine In scores
Let splitScoreLine = scoreLine.Split(New Char() {","})
Where Convert.ToInt32(splitName(2)) = Convert.ToInt32(splitScoreLine(0))
Select New With
{.Last = splitName(0),
.First = splitName(1),
.ExamScores = (From scoreAsText In splitScoreLine Skip 1
Select Convert.ToInt32(scoreAsText)).ToList()}
For Each s In queryNamesScores2
Console.WriteLine("The average score of " & s.First & " " &
s.Last & " is " & s.ExamScores.Average())
Next