Effective Using LINQ To SQL (1) - 分頁技巧

摘要:Effective Using LINQ To SQL (1) - 分頁技巧

Effective Using LINQ To SQL (1) - 分頁技巧
 
文/黃忠成
 
 LINQ To SQL支援了SkipTake兩個LINQ函式,這意味著我們只要結合兩者,就能做出以往不容易做出的分頁擷取資料功能。

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication19
{
    class Program
    {
        static void Main(string[] args)
        {
            NorthwindDataContext context = new NorthwindDataContext();
            context.Log = Console.Out;
            int page = 2;
            var result = (from s1 in context.Customers
                          orderby s1.CustomerID select s1).Skip(page * 10).Take(10);
            foreach (var item in result)
                Console.WriteLine(item.CustomerID);
            Console.ReadLine();
        }
    }
}
以上這段程式的意思是,將Customers資料表以CustomerID正向排序,然後以每頁10筆的單位,取得第20-30(也就是第三頁)的資料,下面是其執行結果及SQL Output。

 

SELECT [t1].[CustomerID], [t1].[CompanyName], [t1].[ContactName], [t1].[ContactT
itle], [t1].[Address], [t1].[City], [t1].[Region], [t1].[PostalCode], [t1].[Coun
try], [t1].[Phone], [t1].[Fax], [t1].[NOTES], [t1].[TEST_ID]
FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY [t0].[CustomerID]) AS [ROW_NUMBER], [t0].
[CustomerID], [t0].[CompanyName], [t0].[ContactName], [t0].[ContactTitle], [t0].
[Address], [t0].[City], [t0].[Region], [t0].[PostalCode], [t0].[Country], [t0].[
Phone], [t0].[Fax], [t0].[NOTES], [t0].[TEST_ID]
    FROM [dbo].[Customers] AS [t0]
    ) AS [t1]
WHERE [t1].[ROW_NUMBER] BETWEEN @p0 + 1 AND @p0 + @p1
ORDER BY [t1].[ROW_NUMBER]
-- @p0: Input Int (Size = 0; Prec = 0; Scale = 0) [20]
-- @p1: Input Int (Size = 0; Prec = 0; Scale = 0) [10]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.21022.8
 
EASTC
ERNSH
FAMIA
FISSA
FOLIG
FOLKO
FRANK
FRANR
FRANS
FURIB
LINQ To SQL善用了SQL Server 2005的ROW_NUMBER指令來完成Skip與Take的功能。
不過,說實在的,分頁其實最常用在於UI顯示的部份,尤其是ASP.NET應用程式上,而ASP.NET 3.5所提供的LINQDataSource控件已自動會處理分頁動作,所以,設計師自行處理分頁的機會變少了許多。
 Windows FormWPF,因為沒有LINQDataSource可用,所以要處理分頁,得自己來才行,不過,這複雜度可不是僅呼叫SkipTake就能處理了,必須自己實做類似BindingSource的控件才行。