Ange åtgärder (C#)

Ange åtgärder i LINQ refererar till frågeåtgärder som skapar en resultatuppsättning baserat på förekomsten eller frånvaron av motsvarande element i samma eller separata samlingar.

Viktigt!

Dessa exempel använder en System.Collections.Generic.IEnumerable<T> datakälla. Datakällor som baseras på System.Linq.IQueryProvider använder System.Linq.IQueryable<T> och uttrycksträd. Uttrycksträd har begränsningar för den tillåtna C#-syntaxen. Dessutom kan varje IQueryProvider datakälla, till exempel EF Core , införa fler begränsningar. Kontrollera dokumentationen för din datakälla.

Metodnamn beskrivning Syntax för C#-frågeuttryck Mer information
Distinct eller DistinctBy Tar bort dubblettvärden från en samling. Ej tillämpbart. Enumerable.Distinct
Enumerable.DistinctBy
Queryable.Distinct
Queryable.DistinctBy
Except eller ExceptBy Returnerar den angivna skillnaden, vilket innebär elementen i en samling som inte visas i en andra samling. Ej tillämpbart. Enumerable.Except
Enumerable.ExceptBy
Queryable.Except
Queryable.ExceptBy
Intersect eller IntersectBy Returnerar den angivna skärningspunkten, vilket innebär element som visas i var och en av två samlingar. Ej tillämpbart. Enumerable.Intersect
Enumerable.IntersectBy
Queryable.Intersect
Queryable.IntersectBy
Union eller UnionBy Returnerar den angivna unionen, vilket innebär unika element som visas i någon av två samlingar. Ej tillämpbart. Enumerable.Union
Enumerable.UnionBy
Queryable.Union
Queryable.UnionBy

Distinct och DistinctBy

I följande exempel visas Enumerable.Distinct-metodens beteende på en sekvens av strängar. Den returnerade sekvensen innehåller de unika elementen från indatasekvensen.

Bild som visar beteendet för 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
 */

DistinctBy är en alternativ metod för Distinct som tar en keySelector. keySelector Används som jämförelsediskriminering av källtypen. I följande kod diskrimineras ord baserat på deras Length, och det första ordet i varje längd visas:

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

I följande exempel visas beteendet för Enumerable.Except. Den returnerade sekvensen innehåller endast elementen från den första indatasekvensen som inte finns i den andra indatasekvensen.

Bild som visar åtgärden Except()

Kommentar

I följande exempel i den här artikeln används vanliga datakällor för det här området.
Varje Student har en betygsnivå, en primär avdelning och en serie poäng. En Teacher har också en City egenskap som identifierar det campus där läraren har klasser. A Department har ett namn och en referens till en Teacher som fungerar som avdelningschef.
Du hittar exempeldatauppsättningen i källdatabasen.

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

Kommentar

Du kan läsa vanliga datakällor för det här området i artikeln Översikt över vanliga frågeoperatorer .

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

Metoden ExceptBy är ett alternativ till Except som tar två sekvenser av eventuellt heterogena typer och en keySelector. keySelector är av samma typ som den första samlingens typ. Överväg att utesluta följande Teacher matris- och lärar-ID:t. Om du vill hitta lärare i den första samlingen som inte finns i den andra samlingen kan du projicera lärarens ID på den andra samlingen:

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

I föregående C#-kod:

  • Matrisen teachers filtreras endast till de lärare som inte finns i matrisen teachersToExclude .
  • Matrisen teachersToExcludeID innehåller värdet för alla avdelningschefer.
  • Anropet till ExceptBy resulterar i en ny uppsättning värden som skrivs till konsolen.

Den nya uppsättningen värden är av typen Teacher, vilket är typen av den första samlingen. Varje teacher i matrisen teachers som inte har något motsvarande ID-värde i matrisen teachersToExclude skrivs ut på konsolen.

Intersect och IntersectBy

I följande exempel visas beteendet av Enumerable.Intersect. Den returnerade sekvensen innehåller de element som är gemensamma för båda indatasekvenserna.

Bild som visar skärningspunkten mellan två sekvenser

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

Metoden IntersectBy är ett alternativt tillvägagångssätt till Intersect som tar två sekvenser av möjligen heterogena typer och en keySelector. keySelector används som den komparativa diskriminatorn för den andra samlingens typ. Överväg följande elev- och lärarrayer. Frågan matchar objekt i varje sekvens efter namn för att hitta de elever som också är lärare:

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

I föregående C#-kod:

  • Frågan skapar skärningspunkten för Teacher och Student genom att jämföra namn.
  • Endast personer som finns i båda matriserna finns i den resulterande sekvensen.
  • De resulterande Student instanserna skrivs till konsolen.

Union och UnionBy

I följande exempel visas en union-åtgärd på två sekvenser med strängar. Den returnerade sekvensen innehåller de unika elementen från båda indatasekvenserna.

Bild som visar union av två sekvenser.

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

Metoden UnionBy är ett alternativt tillvägagångssätt till Union som tar två sekvenser av samma typ och en keySelector. keySelector Används som jämförelsediskriminering av källtypen. Följande fråga skapar en lista över alla personer som antingen är elever eller lärare. Elever som också är lärare läggs bara till i facket en gång:

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

I föregående C#-kod:

  • Matriserna teachers och students vävs samman med deras namn som nyckelväljare.
  • De resulterande namnen skrivs till konsolen.

Se även