Udostępnij za pośrednictwem


Ustawianie operacji (C#)

Ustawianie operacji w LINQ odnosi się do operacji zapytań, które generują zestaw wyników na podstawie obecności lub braku równoważnych elementów w ramach tych samych lub oddzielnych kolekcji.

Ważne

Te przykłady używają System.Collections.Generic.IEnumerable<T> źródła danych. Źródła danych oparte na System.Linq.IQueryProviderSystem.Linq.IQueryable<T> źródłach danych i drzewach wyrażeń. Drzewa wyrażeń mają ograniczenia dotyczące dozwolonej składni języka C#. Ponadto każde IQueryProvider źródło danych, takie jak EF Core , może nakładać więcej ograniczeń. Zapoznaj się z dokumentacją źródła danych.

Nazwy metod opis Składnia wyrażeń zapytań języka C# Więcej informacji
Distinct lub DistinctBy Usuwa zduplikowane wartości z kolekcji. Nie dotyczy. Enumerable.Distinct
Enumerable.DistinctBy
Queryable.Distinct
Queryable.DistinctBy
Except lub ExceptBy Zwraca różnicę zestawu, co oznacza, że elementy jednej kolekcji, które nie są wyświetlane w drugiej kolekcji. Nie dotyczy. Enumerable.Except
Enumerable.ExceptBy
Queryable.Except
Queryable.ExceptBy
Intersect lub IntersectBy Zwraca skrzyżowanie zestawu, co oznacza, że elementy, które pojawiają się w każdej z dwóch kolekcji. Nie dotyczy. Enumerable.Intersect
Enumerable.IntersectBy
Queryable.Intersect
Queryable.IntersectBy
Union lub UnionBy Zwraca unię zestawu, co oznacza unikatowe elementy, które pojawiają się w jednej z dwóch kolekcji. Nie dotyczy. Enumerable.Union
Enumerable.UnionBy
Queryable.Union
Queryable.UnionBy

Distinct i DistinctBy

Poniższy przykład przedstawia zachowanie Enumerable.Distinct metody w sekwencji ciągów. Zwrócona sekwencja zawiera unikatowe elementy z sekwencji danych wejściowych.

Grafika przedstawiająca zachowanie funkcji Distinct()

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
 */

Jest DistinctBy to alternatywne podejście, Distinct które przyjmuje keySelectorwartość . Element keySelector jest używany jako porównawczy dyskryminujący typ źródła. W poniższym kodzie wyrazy są dyskryminowane na podstawie ich Length, a pierwsze słowo każdej długości jest wyświetlane:

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 i ExceptBy

W poniższym przykładzie przedstawiono zachowanie klasy Enumerable.Except. Zwrócona sekwencja zawiera tylko elementy z pierwszej sekwencji wejściowej, które nie znajdują się w drugiej sekwencji danych wejściowych.

Grafika przedstawiająca akcję z wyjątkiem()

W poniższych przykładach w tym artykule użyto typowych źródeł danych dla tego obszaru:

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; }
}

Każdy z nich Student ma poziom klasy, dział podstawowy i serię wyników. Obiekt Teacher ma również właściwość identyfikującą City kampus, w którym nauczyciel posiada zajęcia. Element Department ma nazwę i odwołanie do osoby Teacher , która służy jako szef działu.

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
 */

Metoda ExceptBy jest alternatywnym podejściem Except , które przyjmuje dwie sekwencje prawdopodobnie heterogenicznych typów i keySelector. Jest keySelector to ten sam typ co typ pierwszej kolekcji. Rozważmy następującą Teacher tablicę i identyfikatory nauczycieli, które mają zostać wykluczone. Aby znaleźć nauczycieli w pierwszej kolekcji, które nie znajdują się w drugiej kolekcji, możesz zaprojektować identyfikator nauczyciela w drugiej kolekcji:

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}");
}

W poprzednim kodzie języka C#:

  • Tablica teachers jest filtrowana tylko do tych nauczycieli, którzy nie należą do tablicy teachersToExclude .
  • Tablica teachersToExclude zawiera ID wartość dla wszystkich szefów działu.
  • Wywołanie metody powoduje ExceptBy utworzenie nowego zestawu wartości zapisanych w konsoli programu .

Nowy zestaw wartości jest typu Teacher, który jest typem pierwszej kolekcji. Każda teacher z teachers tablicy, która nie ma odpowiedniej wartości identyfikatora teachersToExclude w tablicy, jest zapisywana w konsoli programu .

Intersect i IntersectBy

W poniższym przykładzie przedstawiono zachowanie klasy Enumerable.Intersect. Zwrócona sekwencja zawiera elementy wspólne dla obu sekwencji wejściowych.

Grafika przedstawiająca przecięcie dwóch sekwencji

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
 */

Metoda IntersectBy jest alternatywnym podejściem Intersect , które przyjmuje dwie sekwencje prawdopodobnie heterogenicznych typów i keySelector. Element keySelector jest używany jako porównawczy dyskryminujący typ drugiej kolekcji. Weź pod uwagę następujące tablice uczniów i nauczycieli. Zapytanie pasuje do elementów w każdej sekwencji według nazwy, aby znaleźć tych uczniów, którzy nie są również nauczycielami:

foreach (Student person in
    students.IntersectBy(
        teachers.Select(t => (t.First, t.Last)), s => (s.FirstName, s.LastName)))
{
    Console.WriteLine($"{person.FirstName} {person.LastName}");
}

W poprzednim kodzie języka C#:

  • Zapytanie tworzy przecięcie elementów Teacher i Student przez porównanie nazw.
  • W wynikowej sekwencji znajdują się tylko osoby znajdujące się w obu tablicach.
  • Wynikowe Student wystąpienia są zapisywane w konsoli programu .

Union i UnionBy

W poniższym przykładzie przedstawiono operację unii na dwóch sekwencjach ciągów. Zwrócona sekwencja zawiera unikatowe elementy z obu sekwencji wejściowych.

Grafika przedstawiająca związek dwóch sekwencji.

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
*/

Metoda UnionBy jest alternatywną metodą Union , która przyjmuje dwie sekwencje tego samego typu i keySelector. Element keySelector jest używany jako porównawczy dyskryminujący typ źródła. Poniższe zapytanie tworzy listę wszystkich osób, które są uczniami lub nauczycielami. Uczniowie, którzy są również nauczycielami, są dodawani do związków zawodowych tylko raz:

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}");
}

W poprzednim kodzie języka C#:

  • Tablice teachers i students są tkane razem przy użyciu ich nazw jako selektora kluczy.
  • Nazwy wynikowe są zapisywane w konsoli programu .

Zobacz też