Partager via


Procédure : retourner ou ignorer des éléments d'une séquence (LINQ to SQL)

Utilisez l'opérateur Take<TSource> pour retourner un nombre donné d'éléments dans une séquence et ignorer le reste.

Utilisez l'opérateur Skip<TSource> pour ignorer un nombre donné d'éléments dans une séquence et retourner le reste.

RemarqueRemarque

Take<TSource> et Skip<TSource> sont soumis à certaines limites lorsqu'ils sont utilisés dans des requêtes SQL Server 2000.Pour plus d'informations, consultez « Exceptions d'ignorance (Skip) et d'acceptation (Take) dans SQL Server 2000 » dans Dépannage (LINQ to SQL).

LINQ to SQL traduit Skip<TSource> à l'aide d'une sous-requête avec la clause SQL NOT EXISTS. Cette traduction présente les limites suivantes :

  • L'argument doit être un jeu. Les multijeux ne sont pas pris en charge, même s'ils sont ordonnés.

  • La requête générée peut être beaucoup plus complexe que celle qui est générée pour la requête de base sur laquelle Skip<TSource> est appliqué. Cette complexité peut entraîner une dégradation des performances ou un délai d'expiration.

Exemple

L'exemple suivant utilise Take pour sélectionner les cinq premiers Employees embauchés. Notez que la collection est d'abord triée par HireDate.

Dim firstHiredQuery = _
    From emp In db.Employees _
    Select emp _
    Order By emp.HireDate _
    Take 5

For Each empObj As Employee In firstHiredQuery
    Console.WriteLine("{0}, {1}", empObj.EmployeeID, _
        empObj.HireDate)
Next
IQueryable<Employee> firstHiredQuery =
    (from emp in db.Employees
    orderby emp.HireDate
    select emp)
    .Take(5);

foreach (Employee empObj in firstHiredQuery)
{
    Console.WriteLine("{0}, {1}", empObj.EmployeeID,
        empObj.HireDate);
}

L'exemple suivant utilise Skip<TSource> pour sélectionner tous les Products exceptés les dix produits les plus chers.

Dim lessExpensiveQuery = _
    From prod In db.Products _
    Select prod _
    Order By prod.UnitPrice Descending _
    Skip 10

For Each prodObj As Product In lessExpensiveQuery
    Console.WriteLine(prodObj.ProductName)
Next
IQueryable<Product> lessExpensiveQuery =
    (from prod in db.Products
    orderby prod.UnitPrice descending
    select prod)
    .Skip(10);

foreach (Product prodObj in lessExpensiveQuery)
{
    Console.WriteLine(prodObj.ProductName);
}

L'exemple suivant combine les méthodes Skip<TSource> et Take<TSource> pour ignorer les cinquante premiers enregistrements et retourner les dix suivants.

Dim custQuery2 = _
    From cust In db.Customers _
    Order By (cust.ContactName) _
    Select cust _
    Skip 50 _
    Take 10

For Each custRecord As Customer In custQuery2
    Console.WriteLine(custRecord.ContactName)
Next
var custQuery2 =
    (from cust in db.Customers
    orderby cust.ContactName
    select cust)
    .Skip(50).Take(10);

foreach (var custRecord in custQuery2)
{
    Console.WriteLine(custRecord.ContactName);
}

Les opérations Take<TSource> et Skip<TSource> sont bien définies uniquement sur les jeux ordonnés. La sémantique des jeux ou des multijeux non ordonnés n'est pas définie.

Du fait des limitations de classement dans SQL, LINQ to SQL tente de déplacer le classement de l'argument de l'opérateur Take<TSource> ou Skip<TSource> vers le résultat de l'opérateur.

RemarqueRemarque

La traduction est différente pour SQL Server 2000 et SQL Server 2005.Si vous envisagez d'utiliser Skip<TSource> avec une requête d'un niveau de complexité quelconque, utilisez SQL Server 2005.

Considérez la requête LINQ to SQL suivante pour SQL Server 2000 :

Dim custQuery3 = _
    From custs In db.Customers _
    Where custs.City = "London" _
    Select custs _
    Order By custs.CustomerID _
    Skip 1 _
    Take 1

For Each custObj In custQuery3
    Console.WriteLine(custObj.CustomerID)
Next
IQueryable<Customer> custQuery3 =
    (from custs in db.Customers
     where custs.City == "London"
     orderby custs.CustomerID
     select custs)
    .Skip(1).Take(1);

foreach (var custObj in custQuery3)
{
    Console.WriteLine(custObj.CustomerID);
}

LINQ to SQL déplace le classement à la fin du code SQL, comme suit :

SELECT TOP 1 [t0].[CustomerID], [t0].[CompanyName],
FROM [Customers] AS [t0]
WHERE (NOT (EXISTS(
    SELECT NULL AS [EMPTY]
    FROM (
        SELECT TOP 1 [t1].[CustomerID]
        FROM [Customers] AS [t1]
        WHERE [t1].[City] = @p0
        ORDER BY [t1].[CustomerID]
        ) AS [t2]
    WHERE [t0].[CustomerID] = [t2].[CustomerID]
    ))) AND ([t0].[City] = @p1)
ORDER BY [t0].[CustomerID]

Lorsque Take<TSource> et Skip<TSource> sont enchaînés, l'ensemble du classement spécifié doit être cohérent. Si ce n'est pas le cas, les résultats ne sont pas définis.

Pour les arguments intégraux constants non négatifs basés sur la spécification SQL, Take<TSource> et Skip<TSource> sont bien définis.

Voir aussi

Référence

Traduction des opérateurs de requête standard (LINQ to SQL)

Autres ressources

Exemples de requêtes (LINQ to SQL)