共用方式為


HOW TO:傳回或略過序列中的項目 (LINQ to SQL)

更新: November 2007

使用 Take<TSource> 運算子傳回序列中指定數目的項目,然後略過其餘的項目。

使用 Skip<TSource> 運算子略過序列中指定數目的項目,然後傳回其餘的項目。

注意事項:

使用 Take<TSource>Skip<TSource> 查詢 SQL Server 2000 時,會有特定限制。如需詳細資訊,請參閱疑難排解 (LINQ to SQL) 中的<SQL Server 2000 中的 Skip 和 Take 例外狀況>一節。

LINQ to SQL 會使用具有 SQL NOT EXISTS 子句的子查詢來轉譯 Skip<TSource>。這項轉譯具有下列限制:

  • 引數必須為集合。即使多重集 (Multiset) 已排序,仍不支援多重集。

  • 產生的查詢可能會比已套用 Skip<TSource> 之基底查詢所產生的查詢更為複雜。這種複雜性會導致效能降低甚或逾時。

範例

下列範例會使用 Take 來選取前五名雇用的 Employees。請注意,此集合會先按照 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);
}

下列範例會使用 Skip<TSource> 來選取除了 10 項最貴 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);
}

下列範例會結合 Skip<TSource>Take<TSource> 方法略過前 50 筆記錄,然後傳回接下來的 10 筆記錄。

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

Take<TSource>Skip<TSource> 作業僅針對已排序的集合加以妥善定義。並未定義未排序集合或多重集 (Multiset) 的語意 (Semantics)。

由於在 SQL 中排序的限制,LINQ to SQL 會嘗試將 Take<TSource>Skip<TSource> 運算子的引數排序移至運算子的結果。

注意事項:

SQL Server 2000 和 SQL Server 2005 的轉譯有所不同。如果您打算使用 Skip<TSource> 搭配任何複雜度的查詢,請使用 SQL Server 2005。

請考量下列 SQL Server 2000 的 LINQ to SQL 查詢:

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 會將排序移至 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<TSource>Skip<TSource> 鏈結在一起時,所有指定的排序都必須一致。否則,結果是未定義的。

至於以 SQL 規格為基礎的非負數、常數整數引數,Take<TSource>Skip<TSource> 都已定義妥善。

請參閱

參考

標準查詢運算子轉譯 (LINQ to SQL)

其他資源

查詢範例 (LINQ to SQL)