Requêtes d'analyse unique (LINQ to DataSet)

Les requêtes LINQ (Language-Integrated Query) fonctionnent sur des sources de données qui implémentent l’interface IEnumerable<T> ou l’interface IQueryable<T>. La classe DataTable n’implémentant pas ces deux interfaces, vous devez appeler la méthode AsEnumerable si vous voulez utiliser la DataTable comme source dans la clause From d’une requête LINQ.

L'exemple ci-dessous obtient toutes les commandes en ligne de la table SalesOrderHeader et affiche l'ID de commande, la date de commande et le numéro de commande sur la console.

// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);

DataTable orders = ds.Tables["SalesOrderHeader"];

var query =
    from order in orders.AsEnumerable()
    where order.Field<bool>("OnlineOrderFlag") == true
    select new
    {
        SalesOrderID = order.Field<int>("SalesOrderID"),
        OrderDate = order.Field<DateTime>("OrderDate"),
        SalesOrderNumber = order.Field<string>("SalesOrderNumber")
    };

foreach (var onlineOrder in query)
{
    Console.WriteLine("Order ID: {0} Order date: {1:d} Order number: {2}",
        onlineOrder.SalesOrderID,
        onlineOrder.OrderDate,
        onlineOrder.SalesOrderNumber);
}
' Fill the DataSet.
Dim ds As New DataSet()
ds.Locale = CultureInfo.InvariantCulture
' See the FillDataSet method in the Loading Data Into a DataSet topic.
FillDataSet(ds)

Dim orders As DataTable = ds.Tables("SalesOrderHeader")

Dim query = _
    From order In orders.AsEnumerable() _
    Where order.Field(Of Boolean)("OnlineOrderFlag") = True _
    Select New With { _
        .SalesOrderID = order.Field(Of Integer)("SalesOrderID"), _
        .OrderDate = order.Field(Of DateTime)("OrderDate"), _
        .SalesOrderNumber = order.Field(Of String)("SalesOrderNumber") _
     }

For Each onlineOrder In query
    Console.Write("Order ID: " & onlineOrder.SalesOrderID)
    Console.Write(" Order date: " & onlineOrder.OrderDate)
    Console.WriteLine(" Order number: " & onlineOrder.SalesOrderNumber)
Next

La requête de variable locale est initialisée avec une expression de requête qui opère sur une ou plusieurs sources d’informations en appliquant un ou plusieurs opérateurs de requête parmi les opérateurs de requête standard ou, dans le cas de LINQ to DataSet, des opérateurs spécifiques à la classe DataSet. L'expression de requête de l'exemple précédent utilise deux des opérateurs de requête standard : Where et Select.

La clause Where filtre la séquence en fonction d'une condition : dans ce cas, que l'indicateur OnlineOrderFlag soit défini sur true. L'opérateur Select alloue et retourne un objet énumérable qui capture les arguments transmis à l'opérateur. Dans l'exemple ci-dessus, un type anonyme est créé avec trois propriétés : SalesOrderID, OrderDate et SalesOrderNumber. Les valeurs de ces trois propriétés sont définies selon les valeurs des colonnes SalesOrderID, OrderDate et SalesOrderNumber de la table SalesOrderHeader.

La boucle foreach énumère ensuite l'objet énumérable retourné par Select puis génère les résultats de la requête. Parce que la requête est du type Enumerable, qui implémente IEnumerable<T>, l'évaluation de la requête est différée jusqu'à ce que la variable de requête soit itérée au sein de la boucle foreach. L'évaluation de requête différée permet de conserver les requêtes en tant que valeurs qui peuvent être évaluées plusieurs fois, produisant chaque fois des résultats potentiellement différents.

La méthode Field fournit l'accès aux valeurs de colonne d'un DataRow et le SetField (non illustré dans l'exemple précédent) définit les valeurs de colonne dans un DataRow. Les deux méthodes Field et SetField gèrent les types de valeurs nullables : vous n’avez donc pas à vérifier explicitement s’il y a des valeurs Null. Les deux méthodes sont également des méthodes génériques, ce qui veut dire que vous n’avez pas à effectuer un cast du type de retour. Vous pourriez utiliser l’accesseur de colonne existant dans DataRow (par exemple, o["OrderDate"]), mais il vous faudrait alors effectuer un cast de l’objet de retour vers le type approprié. Si la colonne est nullable, vous devez vérifier si la valeur est Null en utilisant la méthode IsNull. Pour plus d’informations, consultez Méthodes génériques Field et SetField.

Notez que le type de données spécifié dans le paramètre générique T de la méthode Field et de la méthode SetField doit correspondre au type de la valeur sous-jacente, sinon une InvalidCastException est levée. Le nom de la colonne spécifiée doit également correspondre à celui de la colonne dans le DataSet, sinon une ArgumentException est levée. Dans les deux cas, l'exception est levée au moment de l'exécution de l'énumération des données lorsque la requête est exécutée.

Voir aussi