Mengenvorgänge (C#)
Mengenvorgänge in LINQ sind Abfrageoperationen, die ein Resultset erzeugen, das auf dem Vorhandensein oder Fehlen äquivalenter Elemente in derselben oder in einer anderen Auflistung basiert.
Wichtig
In diesen Beispielen wird eine System.Collections.Generic.IEnumerable<T>-Datenquelle verwendet. Datenquellen, die auf System.Linq.IQueryProvider basieren, verwenden System.Linq.IQueryable<T>-Datenquellen und Ausdrucksbaumstrukturen. Ausdrucksbaumstrukturen haben Einschränkungen für die zulässige C#-Syntax. Darüber hinaus kann jede IQueryProvider
-Datenquelle, z. B. EF Core, weitere Einschränkungen erzwingen. Konsultieren Sie die Dokumentation für Ihre Datenquelle.
Methodennamen | BESCHREIBUNG | C#-Abfrageausdruckssyntax | Weitere Informationen |
---|---|---|---|
Distinct oder DistinctBy |
Entfernt doppelte Werte aus einer Auflistung | Nicht zutreffend. | Enumerable.Distinct Enumerable.DistinctBy Queryable.Distinct Queryable.DistinctBy |
Except oder ExceptBy |
Gibt die Unterschiedsmenge zurück, das heißt die Elemente einer Auflistung, die in einer zweiten Auflistung nicht vorkommen. | Nicht zutreffend. | Enumerable.Except Enumerable.ExceptBy Queryable.Except Queryable.ExceptBy |
Intersect oder IntersectBy |
Gibt die Schnittmenge zurück, d.h. die Elemente, die in beiden Auflistungen angezeigt werden | Nicht zutreffend. | Enumerable.Intersect Enumerable.IntersectBy Queryable.Intersect Queryable.IntersectBy |
Union oder UnionBy |
Gibt die Vereinigungsmenge zurück, d.h. eindeutige Elemente, die in einer der beiden Auflistungen angezeigt werden | Nicht zutreffend. | Enumerable.Union Enumerable.UnionBy Queryable.Union Queryable.UnionBy |
Distinct
und DistinctBy
Das folgende Beispiel veranschaulicht das Verhalten der Enumerable.Distinct-Methode in einer Sequenz aus Zeichenfolgen. Die zurückgegebene Sequenz enthält die eindeutigen Elemente aus der Eingabesequenz.
string[] words = ["the", "quick", "brown", "fox", "jumped", "over", "the", "lazy", "dog"];
IEnumerable<string> query = from word in words.Distinct()
select word;
foreach (var str in query)
{
Console.WriteLine(str);
}
/* This code produces the following output:
*
* the
* quick
* brown
* fox
* jumped
* over
* lazy
* dog
*/
DistinctBy
ist ein alternativer Ansatz für die Distinct
-Methode, die ein keySelector
-Element akzeptiert. Der keySelector
wird als Vergleichsdiskriminator des Quelltyps verwendet. Im folgenden Code werden Wörter basierend auf ihrer Length
unterteilt. Das jeweils erste Wort jeder Länge wird angezeigt:
string[] words = ["the", "quick", "brown", "fox", "jumped", "over", "the", "lazy", "dog"];
foreach (string word in words.DistinctBy(p => p.Length))
{
Console.WriteLine(word);
}
// This code produces the following output:
// the
// quick
// jumped
// over
Except
und ExceptBy
Im folgenden Beispiel wird das Verhalten von Enumerable.Except veranschaulicht. Die zurückgegebene Sequenz enthält nur die Elemente aus der ersten Eingabesequenz, die nicht in der zweiten Eingabesequenz vorkommen.
Hinweis
In den folgenden Beispielen in diesem Artikel werden die allgemeinen Datenquellen für diesen Bereich verwendet.
Allen Student
sind eine Klassenstufe, ein primärer Fachbereich und mehrere Bewertungen zugeordnet. Teacher
verfügen auch über eine City
-Eigenschaft, die den Campus identifiziert, auf dem die Lehrkraft unterrichtet. Eine Department
hat einen Namen und einen Verweis auf eine Teacher
, die den Fachbereich leitet.
Sie finden das Beispieldatensatz im Quell-Repository.
public enum GradeLevel
{
FirstYear = 1,
SecondYear,
ThirdYear,
FourthYear
};
public class Student
{
public required string FirstName { get; init; }
public required string LastName { get; init; }
public required int ID { get; init; }
public required GradeLevel Year { get; init; }
public required List<int> Scores { get; init; }
public required int DepartmentID { get; init; }
}
public class Teacher
{
public required string First { get; init; }
public required string Last { get; init; }
public required int ID { get; init; }
public required string City { get; init; }
}
public class Department
{
public required string Name { get; init; }
public int ID { get; init; }
public required int TeacherID { get; init; }
}
string[] words1 = ["the", "quick", "brown", "fox"];
string[] words2 = ["jumped", "over", "the", "lazy", "dog"];
IEnumerable<string> query = from word in words1.Except(words2)
select word;
foreach (var str in query)
{
Console.WriteLine(str);
}
/* This code produces the following output:
*
* quick
* brown
* fox
*/
Die ExceptBy-Methode ist ein alternativer Ansatz für die Except
-Methode, die zwei Sequenzen möglicherweise heterogener Typen und ein keySelector
-Element akzeptiert. Der keySelector
hat denselben Typ wie die erste Auflistung. Betrachten Sie das folgenden Teacher
-Array und die Lehrkraft-IDs, die ausgeschlossen werden sollen. Um Lehrkräfte in der ersten Auflistung zu finden, die nicht in der zweiten Sammlung enthalten sind, können Sie die Lehrkraft-ID auf die zweite Auflistung projizieren:
int[] teachersToExclude =
[
901, // English
965, // Mathematics
932, // Engineering
945, // Economics
987, // Physics
901 // Chemistry
];
foreach (Teacher teacher in
teachers.ExceptBy(
teachersToExclude, teacher => teacher.ID))
{
Console.WriteLine($"{teacher.First} {teacher.Last}");
}
Im oben stehenden C#-Code ist Folgendes passiert:
- Das
teachers
-Array wird nur nach den Lehrkräften gefiltert, die nicht imteachersToExclude
-Array enthalten sind. - Das
teachersToExclude
-Array enthält denID
-Wert für alle Lehrkräfte, die einen Fachbereich leiten. - Der Aufruf von
ExceptBy
ergibt eine neue Gruppe von Werten, die auf die Konsole geschrieben werden.
Der neue Wertesatz ist vom Typ Teacher
, und das ist der Typ der ersten Auflistung. Jedes teacher
-Element im teachers
-Array, das keinen entsprechenden ID-Wert im teachersToExclude
-Array besitzt, wird an der Konsole ausgegeben.
Intersect
und IntersectBy
Im folgenden Beispiel wird das Verhalten von Enumerable.Intersect veranschaulicht. Die zurückgegebene Sequenz enthält die Elemente, die in beiden Eingabesequenzen verwendet werden.
string[] words1 = ["the", "quick", "brown", "fox"];
string[] words2 = ["jumped", "over", "the", "lazy", "dog"];
IEnumerable<string> query = from word in words1.Intersect(words2)
select word;
foreach (var str in query)
{
Console.WriteLine(str);
}
/* This code produces the following output:
*
* the
*/
Die IntersectBy-Methode ist ein alternativer Ansatz für die Intersect
-Methode, die zwei Sequenzen möglicherweise heterogener Typen und ein keySelector
-Element akzeptiert. Der keySelector
wird als Vergleichsdiskriminator des Typs der zweiten Auflistung verwendet. Betrachten Sie die folgenden Arrays mit Lernenden und Lehrkräften. Die Abfrage gleicht Elemente in jeder Sequenz anhand des Namens ab, um die Kursteilnehmer zu finden, die ebenfalls Lehrer sind:
foreach (Student person in
students.IntersectBy(
teachers.Select(t => (t.First, t.Last)), s => (s.FirstName, s.LastName)))
{
Console.WriteLine($"{person.FirstName} {person.LastName}");
}
Im oben stehenden C#-Code ist Folgendes passiert:
- Die Abfrage erzeugt die Schnittmenge von
Teacher
undStudent
durch einen Vergleich der Namen. - Nur Personen, die sich in beiden Arrays finden, sind in der resultierenden Sequenz vorhanden.
- Die resultierenden
Student
-Instanzen werden an die Konsole ausgegeben.
Union
und UnionBy
Das folgende Beispiel veranschaulicht einen Vereinigungsvorgang zweier Sequenzen aus Zeichenfolgen. Die zurückgegebene Sequenz enthält die eindeutigen Elemente aus beiden Eingabesequenzen.
string[] words1 = ["the", "quick", "brown", "fox"];
string[] words2 = ["jumped", "over", "the", "lazy", "dog"];
IEnumerable<string> query = from word in words1.Union(words2)
select word;
foreach (var str in query)
{
Console.WriteLine(str);
}
/* This code produces the following output:
*
* the
* quick
* brown
* fox
* jumped
* over
* lazy
* dog
*/
Die UnionBy-Methode ist ein alternativer Ansatz für die Union
-Methode, die zwei Sequenzen desselben Typs und ein keySelector
-Element akzeptiert. Der keySelector
wird als Vergleichsdiskriminator des Quelltyps verwendet. Die folgende Abfrage erzeugt die Liste aller Personen, die entweder Lernende oder Lehrkräfte sind. Lernende, die auch Lehrkräfte sind, werden der Vereinigung nur einmal hinzugefügt:
foreach (var person in
students.Select(s => (s.FirstName, s.LastName)).UnionBy(
teachers.Select(t => (FirstName: t.First, LastName: t.Last)), s => (s.FirstName, s.LastName)))
{
Console.WriteLine($"{person.FirstName} {person.LastName}");
}
Im oben stehenden C#-Code ist Folgendes passiert:
- Die Arrays
teachers
undstudents
werden anhand der Namen als Schlüsselselektor vereinigt. - Die resultierenden Namen werden an der Konsole ausgegeben.