Zurückgeben oder Überspringen von Elementen in einer Sequenz
Verwenden Sie den Take-Operator, um eine bestimmte Anzahl von Elementen in einer Sequenz zurückzugeben und den Rest zu überspringen.
Verwenden Sie den Skip-Operator um eine bestimmte Anzahl von Elementen in einer Sequenz zu überspringen und den Rest zurückzugeben.
Hinweis
Take und Skip weisen bestimmte Einschränkungen auf, wenn sie für Abfragen in SQL Server 2000 verwendet werden. Weitere Informationen finden Sie im Eintrag „Überspringen und Behandeln von Ausnahmen in SQL Server 2000“ unter Problembehandlung.
LINQ to SQL übersetzt Skip mithilfe einer Unterabfrage mit der SQL NOT EXISTS
-Klausel. Diese Übersetzung weist die folgenden Einschränkungen auf:
Das Argument muss ein Satz sein. Multisets werden nicht unterstützt, auch dann nicht, wenn diese geordnet sind.
Die erzeugte Abfrage kann wesentlich komplexer sein als die Abfrage, die für die Basisabfrage erstellt wurde, auf die Skip angewendet wird. Diese Komplexität kann zu einer Abnahme der Leistung oder sogar zu einer Zeitüberschreitung führen.
Beispiel 1
Im folgenden Beispiel wird Take
verwendet, um die ersten fünf eingestellten Employees
auszuwählen. Beachten Sie, dass die Auflistung zuerst nach HireDate
sortiert wird.
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);
}
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
Beispiel 2
Im folgenden Beispiel wird Skip verwendet, um alle außer den zehn teuersten Products
auszuwählen.
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);
}
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
Beispiel 3
Im folgenden Beispiel werden die Skip-Methode und die Take-Methode kombiniert, um die ersten 50 Datensätze zu überspringen und dann die nächsten zehn zurückzugeben.
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);
}
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
Die Take-Operation und die Skip-Operation sind nur bei geordneten Sätzen gut definiert. Die Semantik für ungeordnete Sätze oder Multisets ist nicht definiert.
Aufgrund der Sortierungseinschränkungen in SQL versucht LINQ to SQL, die Sortierung des Arguments für den Operator Take oder Skip auf das Operatorergebnis zu verlagern.
Hinweis
Die Übersetzung unterscheidet sich für SQL Server 2000 und SQL Server 2005. Wenn Sie planen, Skip mit einer komplexeren Abfrage einzusetzen, verwenden Sie SQL Server 2005.
Betrachten Sie die folgende LINQ to SQL-Abfrage für SQL Server 2000:
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);
}
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
LINQ to SQL verschiebt die Sortierung im SQL-Code wie folgt an das Ende:
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]
Wenn Take und Skip verkettet werden, muss die angegebene Sortierung konsistent sein. Andernfalls sind die Ergebnisse nicht definiert.
Für nicht negative, konstante, ganzzahlige Argumente auf Grundlage der SQL-Spezifikation sind Take und Skip klar definiert.