Projektionsvorgänge
Aktualisiert: November 2007
Projektion bezeichnet einen Vorgang, bei dem ein Objekt in eine neue Form transformiert wird, die häufig nur aus den Eigenschaften besteht, die anschließend verwendet werden. Mithilfe der Projektion können Sie einen neuen Typ erstellen, der aus den einzelnen Objekten erstellt wird. Sie können eine Eigenschaft projizieren und eine mathematische Funktion dafür ausführen. Außerdem kann das ursprüngliche Objekt projiziert werden, ohne es zu ändern.
Die Standardabfrageoperator-Methoden, die die Projektion ausführen, werden im folgenden Abschnitt aufgelistet.
Methoden
Methodenname |
Beschreibung |
C#-Abfrageausdruckssyntax |
Visual Basic-Abfrageausdruckssyntax |
Weitere Informationen |
---|---|---|---|---|
Select |
Projiziert Werte, die auf einer Transformationsfunktion basieren. |
select |
Select |
|
SelectMany |
Projiziert Sequenzen von Werten, die auf einer Transformationsfunktion basieren, und fasst sie anschließend in einer Sequenz zusammen. |
Verwendung mehrerer from-Klauseln |
Verwendung mehrerer From-Klauseln |
Beispiele für Abfrageausdruckssyntax
Select
Im folgenden Beispiel wird die select-Klausel in C# oder die Select-Klausel in Visual Basic verwendet, um den ersten Buchstaben der einzelnen Zeichenfolgen aus einer Zeichenfolgenliste zu projizieren.
Dim words As New List(Of String)(New String() {"an", "apple", "a", "day"})
Dim query = From word In words _
Select word.Substring(0, 1)
Dim sb As New System.Text.StringBuilder()
For Each letter As String In query
sb.AppendLine(letter)
Next
' Display the output.
MsgBox(sb.ToString())
' This code produces the following output:
' a
' a
' a
' d
List<string> words = new List<string>() { "an", "apple", "a", "day" };
var query = from word in words
select word.Substring(0, 1);
foreach (string s in query)
Console.WriteLine(s);
/* This code produces the following output:
a
a
a
d
*/
SelectMany
Im folgenden Beispiel werden mehrere from-Klauseln in C# oder From -Klauseln in Visual Basic verwendet, um jedes Wort der einzelnen Zeichenfolgen aus einer Zeichenfolgenliste zu projizieren.
Dim phrases As New List(Of String)(New String() {"an apple a day", "the quick brown fox"})
Dim query = From phrase In phrases _
From word In phrase.Split(" "c) _
Select word
Dim sb As New System.Text.StringBuilder()
For Each str As String In query
sb.AppendLine(str)
Next
' Display the output.
MsgBox(sb.ToString())
' This code produces the following output:
' an
' apple
' a
' day
' the
' quick
' brown
' fox
List<string> phrases = new List<string>() { "an apple a day", "the quick brown fox" };
var query = from phrase in phrases
from word in phrase.Split(' ')
select word;
foreach (string s in query)
Console.WriteLine(s);
/* This code produces the following output:
an
apple
a
day
the
quick
brown
fox
*/
Select und SelectMany im Vergleich
Die Aufgabe sowohl von Select() als auch von SelectMany() besteht darin, einen oder mehrere Ergebniswerte aus Quellwerten zu generieren. Select() generiert einen Ergebniswert für jeden Quellwert. Daher entspricht das Gesamtergebnis einer Auflistung, die dieselbe Anzahl von Elementen wie die Quellauflistung aufweist. SelectMany() erzeugt im Gegensatz dazu ein einzelnes Gesamtergebnis, das verkettete Unterauflistungen von jedem Quellwert enthält. Die als Argument an SelectMany() übergebene Transformationsfunktion muss für jeden Quellwert eine Sequenz von Werten zurückgeben, die aufgelistet werden können. Diese auflistbaren Sequenzen werden dann durch SelectMany() zu einer großen Sequenz verkettet.
Die folgenden beiden Abbildungen zeigen den konzeptionellen Unterschied zwischen den Aktionen dieser beiden Methoden. In beiden Fällen wird davon ausgegangen, dass die Auswahlfunktion (Transformationsfunktion) das Blumenarrangement aus jedem Quellwert auswählt.
Aus der Abbildung ist ersichtlich, dass Select() eine Auflistung zurückgibt, die über dieselbe Anzahl von Elementen wie die Quellauflistung verfügt.
Diese Abbildung zeigt, wie die Zwischensequenz von Arrays von SelectMany() zu einem endgültigen Ergebniswert verkettet wird, der jeden Wert aus den einzelnen Zwischenarrays enthält.
Codebeispiel
Im folgenden Beispiel wird das Verhalten von Select() und SelectMany() verglichen. Durch den Code wird ein "Strauß" aus Blumen gebildet, indem die ersten beiden Elemente aus jeder Liste mit Blumennamen in die Quellauflistung eingefügt werden. In diesem Beispiel entspricht der von der Transformationsfunktion Select<TSource, TResult>(IEnumerable<TSource>, Func<TSource, TResult>) verwendete "Einzelwert" selbst einer Werteauflistung. Die zusätzliche foreach-Schleife (For Each-Schleife in Visual Basic) ist erforderlich, damit jede Zeichenfolge in den einzelnen Untersequenzen aufgelistet wird.
Class Bouquet
Public Flowers As List(Of String)
End Class
Sub SelectVsSelectMany()
Dim bouquets As New List(Of Bouquet)(New Bouquet() { _
New Bouquet With {.Flowers = New List(Of String)(New String() {"sunflower", "daisy", "daffodil", "larkspur"})}, _
New Bouquet With {.Flowers = New List(Of String)(New String() {"tulip", "rose", "orchid"})}, _
New Bouquet With {.Flowers = New List(Of String)(New String() {"gladiolis", "lily", "snapdragon", "aster", "protea"})}, _
New Bouquet With {.Flowers = New List(Of String)(New String() {"larkspur", "lilac", "iris", "dahlia"})}})
Dim output As New System.Text.StringBuilder
' Select()
Dim query1 = bouquets.Select(Function(b) b.Flowers)
output.AppendLine("Using Select():")
For Each flowerList In query1
For Each str As String In flowerList
output.AppendLine(str)
Next
Next
' SelectMany()
Dim query2 = bouquets.SelectMany(Function(b) b.Flowers)
output.AppendLine(vbCrLf & "Using SelectMany():")
For Each str As String In query2
output.AppendLine(str)
Next
' Display the output
MsgBox(output.ToString())
' This code produces the following output:
'
' Using Select():
' sunflower
' daisy
' daffodil
' larkspur
' tulip
' rose
' orchid
' gladiolis
' lily
' snapdragon
' aster
' protea
' larkspur
' lilac
' iris
' dahlia
' Using SelectMany()
' sunflower
' daisy
' daffodil
' larkspur
' tulip
' rose
' orchid
' gladiolis
' lily
' snapdragon
' aster
' protea
' larkspur
' lilac
' iris
' dahlia
End Sub
class Bouquet
{
public List<string> Flowers { get; set; }
}
static void SelectVsSelectMany()
{
List<Bouquet> bouquets = new List<Bouquet>() {
new Bouquet { Flowers = new List<string> { "sunflower", "daisy", "daffodil", "larkspur" }},
new Bouquet{ Flowers = new List<string> { "tulip", "rose", "orchid" }},
new Bouquet{ Flowers = new List<string> { "gladiolis", "lily", "snapdragon", "aster", "protea" }},
new Bouquet{ Flowers = new List<string> { "larkspur", "lilac", "iris", "dahlia" }}
};
// *********** Select ***********
IEnumerable<List<string>> query1 = bouquets.Select(bq => bq.Flowers);
// ********* SelectMany *********
IEnumerable<string> query2 = bouquets.SelectMany(bq => bq.Flowers);
Console.WriteLine("Results by using Select():");
// Note the extra foreach loop here.
foreach (IEnumerable<String> collection in query1)
foreach (string item in collection)
Console.WriteLine(item);
Console.WriteLine("\nResults by using SelectMany():");
foreach (string item in query2)
Console.WriteLine(item);
/* This code produces the following output:
Results by using Select():
sunflower
daisy
daffodil
larkspur
tulip
rose
orchid
gladiolis
lily
snapdragon
aster
protea
larkspur
lilac
iris
dahlia
Results by using SelectMany():
sunflower
daisy
daffodil
larkspur
tulip
rose
orchid
gladiolis
lily
snapdragon
aster
protea
larkspur
lilac
iris
dahlia
*/
}
Weitere Informationen zur Projektion
Siehe auch
Konzepte
Übersicht über Standardabfrageoperatoren