from clause (Referenční dokumentace jazyka C#)

Výraz dotazu musí začínat from klauzulí . Kromě toho může výraz dotazu obsahovat dílčí dotazy, které také začínají from klauzulí . Klauzule from určuje následující:

  • Zdroj dat, ve kterém se dotaz nebo dílčí dotaz spustí.

  • Proměnná místního rozsahu, která představuje každý prvek ve zdrojové sekvenci.

Proměnná rozsahu i zdroj dat jsou silného typu. Zdroj dat odkazovaný v from klauzuli musí mít typ IEnumerable , nebo IEnumerable<T> odvozený typ, například IQueryable<T> .

V následujícím příkladu numbers je zdroj dat a num proměnná rozsahu. Všimněte si, že obě proměnné jsou silného typu, i když se používá klíčové slovo 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

Proměnná rozsahu

Kompilátor odvodí typ proměnné rozsahu, když zdroj dat implementuje IEnumerable<T> . Pokud má například zdroj typ , pak je proměnná IEnumerable<Customer> rozsahu odvozena jako Customer . Typ je nutné explicitně zadat pouze v případě, že je zdroj neobecná IEnumerable typ, například ArrayList . Další informace najdete v tématu Jak dotazovat ArrayList pomocí LINQ.

V předchozím num příkladu se odvodí, že je typu int . Vzhledem k tomu, že proměnná rozsahu je silného typu, můžete na ní volat metody nebo ji použít v jiných operacích. Místo psaní můžete například napsat , aby výraz dotazu vrátil sekvenci řetězců select num select num.ToString() místo celých čísel. Nebo můžete napsat , aby výraz vrátil sekvenci select num + 10 14, 11, 13, 12, 10. Další informace najdete v tématu o klauzuli select.

Proměnná rozsahu je jako iterační proměnná v příkazu foreach s výjimkou jednoho velmi důležitého rozdílu: proměnná rozsahu nikdy ve skutečnosti neuchová data ze zdroje. Je to jen syntaktická pohodlí, která umožňuje dotazu popsat, co se stane při spuštění dotazu. Další informace najdete v tématu Úvod do dotazů LINQ (C#).

Složené klauzule from

V některých případech může být každý prvek ve zdrojové sekvenci sám o sobě sekvencí nebo může obsahovat sekvenci. Zdrojem dat může být například objekt, ve kterém každý objekt studenta v sekvenci obsahuje seznam IEnumerable<Student> testovacích skóre. Pro přístup k vnitřnímu seznamu v rámci každého Student prvku můžete použít složené from klauzule. Technika je podobná použití vnořených příkazů foreach. Pokud chcete filtrovat výsledky, můžete do klauzule where nebo orderby přidat klauzule where nebo orderby. from Následující příklad ukazuje posloupnost objektů, z nichž každý obsahuje vnitřní z celých Student List čísel představujících skóre testu. Pro přístup k vnitřnímu seznamu použijte složenou from klauzuli . V případě potřeby můžete vložit klauzule from mezi tyto dvě klauzule.

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

    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 List<Student>
        {
           new Student {LastName="Omelchenko", Scores= new List<int> {97, 72, 81, 60}},
           new Student {LastName="O'Donnell", Scores= new List<int> {75, 84, 91, 39}},
           new Student {LastName="Mortensen", Scores= new List<int> {88, 94, 65, 85}},
           new Student {LastName="Garcia", Scores= new List<int> {97, 89, 85, 82}},
           new Student {LastName="Beebe", Scores= new List<int> {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);
        }

        // Keep the console window open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
/*
scoreQuery:
Omelchenko Score: 97
O'Donnell Score: 91
Mortensen Score: 94
Garcia Score: 97
Beebe Score: 91
*/

Použití více klauzulí z k provedení spojení

Složená from klauzule se používá pro přístup k vnitřním kolekcím v jednom zdroji dat. Dotaz však může obsahovat také více from klauzulí, které generují doplňkové dotazy z nezávislých zdrojů dat. Tato technika umožňuje provádět určité typy operací spojení, které nejsou možné pomocí klauzule join.

Následující příklad ukazuje, jak lze pomocí dvou klauzulí vytvořit from úplné křížové spojení dvou zdrojů dat.

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

Další informace o operacích spojení, které používají více from klauzulí, najdete v tématu Provedení levých vnějších spojení.

Viz také