Delen via


from component (C#Reference)

Een query-expressie moet beginnen met een from component. Daarnaast kan een query-expressie subquery's bevatten, die ook beginnen met een from component. De from component geeft het volgende op:

  • De gegevensbron waarop de query of subquery wordt uitgevoerd.

  • Een lokale bereikvariabele die elk element in de bronreeks vertegenwoordigt.

Zowel de bereikvariabele als de gegevensbron worden sterk getypt. De gegevensbron waarnaar in de from component wordt verwezen, moet een type IEnumerable, IEnumerable<T>of een afgeleid type hebben, zoals IQueryable<T>.

In het volgende voorbeeld numbers is dit de gegevensbron en num de bereikvariabele. Houd er rekening mee dat beide variabelen sterk zijn getypt, ook al wordt het trefwoord var .

class LowNums
{
    static void Main()
    {
        // A simple data source.
        int[] numbers = [5, 4, 1, 3, 9, 8, 6, 7, 2, 0];

        // Create the query.
        // lowNums is an IEnumerable<int>
        var lowNums = from num in numbers
            where num < 5
            select num;

        // Execute the query.
        foreach (int i in lowNums)
        {
            Console.Write(i + " ");
        }
    }
}
// Output: 4 1 3 2 0

De bereikvariabele

De compiler bepaalt het type bereikvariabele wanneer de gegevensbron wordt geïmplementeerd IEnumerable<T>. Als de bron bijvoorbeeld een type IEnumerable<Customer>heeft, wordt de bereikvariabele afgeleid.Customer De enige keer dat u het type expliciet moet opgeven, is wanneer de bron een niet-algemeen IEnumerable type is, zoals ArrayList. Zie Een matrixlijst opvragen met LINQ voor meer informatie.

In het vorige voorbeeld num wordt afgeleid dat het type intis. Omdat de bereikvariabele sterk is getypt, kunt u methoden hierop aanroepen of gebruiken in andere bewerkingen. In plaats van te schrijven select numkunt u bijvoorbeeld schrijven om ervoor te zorgen select num.ToString() dat de query-expressie een reeks tekenreeksen retourneert in plaats van gehele getallen. U kunt ook schrijven select num + 10 om ervoor te zorgen dat de expressie de reeks 14, 11, 13, 12, 10 retourneert. Zie select-component voor meer informatie.

De bereikvariabele lijkt op een iteratievariabele in een foreach-instructie , met uitzondering van één zeer belangrijk verschil: een bereikvariabele slaat nooit daadwerkelijk gegevens op uit de bron. Het is slechts een syntactisch gemak waarmee de query kan beschrijven wat er gebeurt wanneer de query wordt uitgevoerd. Zie Inleiding tot LINQ-query's (C#) voor meer informatie.

Samengesteld uit componenten

In sommige gevallen kan elk element in de bronreeks zelf een reeks zijn of een reeks bevatten. Uw gegevensbron kan bijvoorbeeld een IEnumerable<Student> locatie zijn waarin elk studentobject in de reeks een lijst met testscores bevat. Voor toegang tot de binnenste lijst binnen elk Student element kunt u samengestelde from componenten gebruiken. De techniek lijkt op het gebruik van geneste foreach-instructies . U kunt waar- of orderby-componenten toevoegen aan een from van beide componenten om de resultaten te filteren. In het volgende voorbeeld ziet u een reeks Student objecten, die elk een binnenste List van gehele getallen bevatten die testscores vertegenwoordigen. Gebruik een samengestelde from component om toegang te krijgen tot de binnenste lijst. U kunt indien nodig componenten tussen de twee from componenten invoegen.

class CompoundFrom
{
    // The element type of the data source.
    public class Student
    {
        public required string LastName { get; init; }
        public required List<int> Scores {get; init;}
    }

    static void Main()
    {

        // Use a collection initializer to create the data source. Note that
        // each element in the list contains an inner sequence of scores.
        List<Student> students =
        [
           new Student {LastName="Omelchenko", Scores= [97, 72, 81, 60]},
           new Student {LastName="O'Donnell", Scores= [75, 84, 91, 39]},
           new Student {LastName="Mortensen", Scores= [88, 94, 65, 85]},
           new Student {LastName="Garcia", Scores= [97, 89, 85, 82]},
           new Student {LastName="Beebe", Scores= [35, 72, 91, 70]}
        ];

        // Use a compound from to access the inner sequence within each element.
        // Note the similarity to a nested foreach statement.
        var scoreQuery = from student in students
                         from score in student.Scores
                            where score > 90
                            select new { Last = student.LastName, score };

        // Execute the queries.
        Console.WriteLine("scoreQuery:");
        // Rest the mouse pointer on scoreQuery in the following line to
        // see its type. The type is IEnumerable<'a>, where 'a is an
        // anonymous type defined as new {string Last, int score}. That is,
        // each instance of this anonymous type has two members, a string
        // (Last) and an int (score).
        foreach (var student in scoreQuery)
        {
            Console.WriteLine("{0} Score: {1}", student.Last, student.score);
        }
    }
}
/*
scoreQuery:
Omelchenko Score: 97
O'Donnell Score: 91
Mortensen Score: 94
Garcia Score: 97
Beebe Score: 91
*/

Meerdere van componenten gebruiken om joins uit te voeren

Een samengestelde from component wordt gebruikt voor toegang tot binnenverzamelingen in één gegevensbron. Een query kan echter ook meerdere from componenten bevatten die aanvullende query's genereren uit onafhankelijke gegevensbronnen. Met deze techniek kunt u bepaalde typen joinbewerkingen uitvoeren die niet mogelijk zijn met behulp van de join-component.

In het volgende voorbeeld ziet u hoe twee from componenten kunnen worden gebruikt om een volledige cross join van twee gegevensbronnen te vormen.

class CompoundFrom2
{
    static void Main()
    {
        char[] upperCase = ['A', 'B', 'C'];
        char[] lowerCase = ['x', 'y', 'z'];

        // The type of joinQuery1 is IEnumerable<'a>, where 'a
        // indicates an anonymous type. This anonymous type has two
        // members, upper and lower, both of type char.
        var joinQuery1 =
            from upper in upperCase
            from lower in lowerCase
            select new { upper, lower };

        // The type of joinQuery2 is IEnumerable<'a>, where 'a
        // indicates an anonymous type. This anonymous type has two
        // members, upper and lower, both of type char.
        var joinQuery2 =
            from lower in lowerCase
            where lower != 'x'
            from upper in upperCase
            select new { lower, upper };

        // Execute the queries.
        Console.WriteLine("Cross join:");
        // Rest the mouse pointer on joinQuery1 to verify its type.
        foreach (var pair in joinQuery1)
        {
            Console.WriteLine("{0} is matched to {1}", pair.upper, pair.lower);
        }

        Console.WriteLine("Filtered non-equijoin:");
        // Rest the mouse pointer over joinQuery2 to verify its type.
        foreach (var pair in joinQuery2)
        {
            Console.WriteLine("{0} is matched to {1}", pair.lower, pair.upper);
        }

        // Keep the console window open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
/* Output:
        Cross join:
        A is matched to x
        A is matched to y
        A is matched to z
        B is matched to x
        B is matched to y
        B is matched to z
        C is matched to x
        C is matched to y
        C is matched to z
        Filtered non-equijoin:
        y is matched to A
        y is matched to B
        y is matched to C
        z is matched to A
        z is matched to B
        z is matched to C
        */

Zie Left outer joins uitvoeren voor meer informatie over joinbewerkingen die gebruikmaken van meerdere from componenten.

Zie ook