Condividi tramite


Procedura: restituire o ignorare gli elementi in una sequenza (LINQ to SQL)

Utilizzare l'operatore Take<TSource> per restituire un numero specificato di elementi in una sequenza e ignorare quindi gli elementi rimanenti.

Utilizzare l'operatore Skip<TSource> per ignorare un numero specificato di elementi in una sequenza, quindi restituire gli elementi rimanenti.

NotaNota

Take<TSource> e Skip<TSource> presentano alcune limitazioni quando vengono utilizzati nelle query su SQL Server 2000.Per ulteriori informazioni, vedere la voce relativa alle eccezioni di Skip e Take in SQL Server 2000 in Risoluzione dei problemi (LINQ to SQL).

LINQ to SQL converte Skip<TSource> utilizzando una sottoquery con la clausola SQL NOT EXISTS. Di seguito vengono elencate le limitazioni di questa conversione.

  • L'argomento deve essere un set. I tipi multiset non sono supportati, anche se ordinati.

  • La query generata può essere molto più complessa di quella generata per la query di base a cui viene applicato Skip<TSource>. Questa complessità può provocare una riduzione delle prestazioni o il timeout dell'operazione.

Esempio

Nell'esempio seguente viene utilizzato Take per selezionare i primi cinque dipendenti assunti in Employees. Notare che la raccolta viene prima ordinata per 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);
}

Nell'esempio seguente viene utilizzato Skip<TSource> per selezionare tutti i prodotti tranne i 10 più costosi nella tabella Products.

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);
}

Nell'esempio seguente vengono combinati i metodi Skip<TSource> e Take<TSource> per ignorare i primi 50 record e restituire quindi i 10 successivi.

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);
}

Le operazioni Take<TSource> e Skip<TSource> sono definite correttamente solo per i set ordinati, mentre la semantica per i set non ordinati o i tipi multiset non è definita.

A causa delle limitazioni relative all'ordinamento in SQL, LINQ to SQL tenta di spostare l'ordinamento dell'argomento dell'operatore Take<TSource> o Skip<TSource> nel risultato dell'operatore.

NotaNota

La conversione è diversa per SQL Server 2000 e SQL Server 2005.Se si prevede di utilizzare Skip<TSource> con una query di qualsiasi complessità, utilizzare SQL Server 2005.

Considerare la query LINQ to SQL seguente per 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 sposta l'ordinamento alla fine nel codice SQL, come segue:

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]

Quando Take<TSource> e Skip<TSource> sono concatenati, tutti i tipi di ordinamento specificati devono essere coerenti. In caso contrario i risultati non saranno definiti.

Per gli argomenti di tipo integrale costante non negativi, basati sulla specifica SQL, Take<TSource> e Skip<TSource> sono definiti correttamente.

Vedere anche

Riferimenti

Conversione dell'operatore di query standard (LINQ to SQL)

Altre risorse

Eseguire una query sugli esempi (LINQ to SQL)