from, clause (Référence C#)from clause (C# Reference)

Une expression de requête doit commencer par une clause from.A query expression must begin with a from clause. Une expression de requête peut également contenir des sous-requêtes qui commencent elles aussi par une clause from.Additionally, a query expression can contain sub-queries, which also begin with a from clause. La clause from spécifie les éléments suivants :The from clause specifies the following:

  • La source de données sur laquelle la requête ou la sous-requête est exécutée.The data source on which the query or sub-query will be run.

  • Une variable de portée locale qui représente chaque élément dans la séquence source.A local range variable that represents each element in the source sequence.

La variable de portée et la source de données sont toutes les deux fortement typées.Both the range variable and the data source are strongly typed. La source de données référencée dans la clause from doit avoir un type IEnumerable, IEnumerable<T> ou un type dérivé comme IQueryable<T>.The data source referenced in the from clause must have a type of IEnumerable, IEnumerable<T>, or a derived type such as IQueryable<T>.

Dans l’exemple suivant, numbers est la source de données tandis que num est la variable de portée.In the following example, numbers is the data source and num is the range variable. Notez que les deux variables sont fortement typées même si le mot clé var est utilisé.Note that both variables are strongly typed even through the var keyword is used.

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

Variable de portéeThe Range Variable

Le compilateur déduit le type de la variable de portée quand la source de données implémente IEnumerable<T>.The compiler infers the type of the range variable when the data source implements IEnumerable<T>. Par exemple, si la source a un type IEnumerable<Customer>, la variable de portée est déduite comme étant Customer.For example, if the source has a type of IEnumerable<Customer>, then the range variable is inferred to be Customer. Vous devez spécifier le type de façon explicite uniquement quand la source est un type IEnumerable non générique comme ArrayList.The only time that you must specify the type explicitly is when the source is a non-generic IEnumerable type such as ArrayList. Pour plus d’informations, consultez Guide pratique pour interroger une liste de tableaux avec LINQ.For more information, see How to: Query an ArrayList with LINQ.

Dans l’exemple précédent, num est déduit comme étant de type int.In the previous example num is inferred to be of type int. Comme la variable de portée est fortement typée, vous pouvez appeler des méthodes sur celle-ci ou l’utiliser dans d’autres opérations.Because the range variable is strongly typed, you can call methods on it or use it in other operations. Par exemple, au lieu d’écrire select num, vous pouvez écrire select num.ToString() pour que l’expression de requête retourne une séquence de chaînes à la place d’entiers.For example, instead of writing select num, you could write select num.ToString() to cause the query expression to return a sequence of strings instead of integers. Vous pouvez également écrire select n + 10 pour que l’expression retourne la séquence 14, 11, 13, 12, 10.Or you could write select n + 10 to cause the expression to return the sequence 14, 11, 13, 12, 10. Pour plus d’informations, consultez select, clause.For more information, see select clause.

La variable de portée est semblable à une variable d’itération dans une instruction foreach à une différence près, très importante : une variable de portée ne stocke jamais réellement de données de la source.The range variable is like an iteration variable in a foreach statement except for one very important difference: a range variable never actually stores data from the source. Il s’agit juste d’un avantage syntaxique pratique qui permet à la requête de décrire ce qui se produira lors de son exécution.It just a syntactic convenience that enables the query to describe what will occur when the query is executed. Pour plus d’informations, consultez Introduction aux requêtes LINQ (C#).For more information, see Introduction to LINQ Queries (C#).

Clauses from composéesCompound from Clauses

Dans certains cas, chaque élément dans la séquence source peut être une séquence ou contenir une séquence.In some cases, each element in the source sequence may itself be either a sequence or contain a sequence. Par exemple, votre source de données peut être un IEnumerable<Student> où chaque objet Student dans la séquence contient une liste de notes d’examens.For example, your data source may be an IEnumerable<Student> where each student object in the sequence contains a list of test scores. Pour accéder à la liste interne dans chaque élément Student, vous pouvez utiliser des clauses from composées.To access the inner list within each Student element, you can use compound from clauses. Cette technique est proche de celle consistant à utiliser des instructions foreach imbriquées.The technique is like using nested foreach statements. Vous pouvez ajouter des clauses where ou orderby à l’une et l’autre des clauses from pour filtrer les résultats.You can add where or orderby clauses to either from clause to filter the results. L’exemple suivant présente une séquence d’objets Student et chacun contient un List interne des entiers qui représentent des notes d’examens.The following example shows a sequence of Student objects, each of which contains an inner List of integers representing test scores. Pour accéder à la liste interne, utilisez une clause from composée.To access the inner list, use a compound from clause. Vous pouvez insérer des clauses entre les deux clauses from si nécessaire.You can insert clauses between the two from clauses if necessary.

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

Utilisation de plusieurs clauses from pour effectuer des jointuresUsing Multiple from Clauses to Perform Joins

Une clause from composée est utilisée pour accéder aux collections internes dans une source de données unique.A compound from clause is used to access inner collections in a single data source. Toutefois, une requête peut également contenir plusieurs clauses from qui génèrent des requêtes supplémentaires de sources de données indépendantes.However, a query can also contain multiple from clauses that generate supplemental queries from independent data sources. Cette technique vous permet d’effectuer certains types d’opérations de jointure qui ne sont pas possibles en utilisant la clause join.This technique enables you to perform certain types of join operations that are not possible by using the join clause.

L’exemple suivant montre comment utiliser deux clauses from pour former une jointure croisée complète de deux sources de données.The following example shows how two from clauses can be used to form a complete cross join of two data sources.

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

Pour plus d’informations sur les opérations de jointure qui utilisent plusieurs clauses from, consultez Guide pratique pour effectuer des opérations de jointure personnalisées.For more information about join operations that use multiple from clauses, see How to: Perform Custom Join Operations.

Voir aussiSee Also

Mots clés de requête (LINQ)Query Keywords (LINQ)
Expressions de requête LINQLINQ Query Expressions