Возврат или пропуск элементов последовательности
Для возвращения заданного числа элементов последовательности и пропуска оставшихся используется оператор Take.
Для пропуска заданного числа элементов последовательности и возвращения оставшихся используется оператор Skip.
Примечание.
На методы Take и Skip накладываются некоторые ограничения при их использовании в запросах для SQL Server 2000. Дополнительные сведения см. в статье "Пропуск и выполнение исключений в SQL Server 2000" в разделе "Устранение неполадок".
LINQ to SQL преобразуется Skip с помощью вложенных запросов с предложением SQL NOT EXISTS
. Это преобразование имеет следующие ограничения.
Необходимо задать значение аргумента. Не поддерживаются множественные наборы, даже упорядоченные.
Созданный запрос может быть сложнее, чем запрос, созданный для основного запроса, к которому применен Skip. Это может стать причиной снижения производительности или даже привести к превышению времени ожидания.
Пример 1
В следующем примере для выбора первых пяти принятых на работу Take
используется метод Employees
. Обратите внимание, что коллекция сначала сортируется по HireDate
.
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
Пример 2
В следующем примере для выбора всех Skip, за исключением 10 самых дорогих, используется метод Products
.
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
Пример 3
В следующем примере для пропуска первых 50 и возвращения следующих за ними 10 записей методы Skip и Take объединяются.
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
Методы Take и Skip правильно определяются только для упорядоченных наборов. Семантика для неупорядоченных наборов или множественных наборов не определена.
Из-за ограничений по упорядочению в SQL LINQ to SQL пытается переместить порядок аргумента Take или Skip оператора в результат оператора.
Примечание.
Перевод отличается для SQL Server 2000 и SQL Server 2005. Если вы планируете использовать Skip запрос с любой сложностью, используйте SQL Server 2005.
Рассмотрим следующий запрос LINQ to SQL для 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 перемещает порядок в конец кода SQL следующим образом:
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]
При связывании методов Take и Skip друг с другом все указанные операции упорядочения должны быть согласованы. В противном случае результаты не определены.
Методы Take и Skip правильно определяются для неотрицательных постоянных целочисленных аргументов, соответствующих спецификации SQL.