顯示具有 FETCH 標籤的文章。 顯示所有文章
顯示具有 FETCH 標籤的文章。 顯示所有文章

2018年4月16日 星期一

ASP.NET MVC分頁(.Skip() 與.Take())

之前的文章,提到網頁程式分頁的寫法。
使用SQL 2012起可用的 OFFSET-FETCH,搭配ADO.NET (DataReader)來做分頁(Paging)。

[讀書心得]資料分頁的最佳化,以SQL 2012的OFFSET-FETCH為例
http://mis2000lab.pixnet.net/blog/post/33836306


[習題]上集 Ch 14-4 撰寫ADO.NET DataReader的分頁程式#3(搭配SQL 2012指令 OFFSET...FETCH)
http://mis2000lab.pixnet.net/blog/post/35057446  或是
https://mis2000lab.blogspot.tw/2018/04/ch-14-4-adonet-datareader3sql-2012.html


這個範例改成 ASP.NET MVC 的 LINQ語法,其實大同小異。

原本的SQL指令:
//== ADO.NET 參數的寫法 ==
String SqlStr = "Select test_time, id, title, summary from test Order By id
OFFSET @Page1 ROWS FETCH NEXT @Page2 ROWS ONLY";

        SqlCommand cmd1 = new SqlCommand(SqlStr, Conn);
        cmd1.Parameters.AddWithValue("@Page1", NowPageCount);
        cmd1.Parameters.AddWithValue("@Page2", PageSize);

如果我的說法沒錯的話,這是我「個人」整理出來的重點:
OFFSET X ROWS   代表你忽略了前面幾筆記錄(也就是從這裡  開始讀取,從頭開始算起,第一"頁"的編號請用「零」代表 )
FETCH NEXT Y ROWS ONLY  代表你從「第幾列」向後 讀取 (我 只要 這幾列的記錄即可!)

Offset.....與後面的 FETCH,其實跟下面的 .Skip() 與 .Take() 功能類同。

(from m in _db.UserTables
                orderby m.UserId   // 若寫 descending ,則是反排序(由大到小)
                select m).Skip(NowPageCount).Take(PageSize);


======= 程式碼如下 ======================(start)

        public ActionResult IndexPage(int id=1)
        {
            // id變數,目前位於第幾頁?
            // PageSize變數,每一頁,要展示幾筆記錄?         
            int PageSize = 3;

            // NowPageCount,目前正在觀賞這一頁的紀錄
            int NowPageCount = 0;
            if (id == 0)   {
                NowPageCount = (id - 1) * PageSize;    // PageSize,每頁展示3筆紀錄(上面設定過了)
            }

            // 這段指令的 .Skip()與 . Take(),其實跟T-SQL指令的 offset...fetch....很類似(SQL 2012起可用)
            var ListAll = (from m in _db.UserTables
                           orderby m.UserId   // 若寫 descending ,則是反排序(由大到小)
                           select m).Skip(NowPageCount).Take(PageSize);    // .Skip() 從哪裡開始(忽略前面幾筆記錄)。 .Take()呈現幾筆記錄

            if (ListAll == null)
            {   // 找不到任何記錄
                return HttpNotFound();
            }
            else   {
                return View(ListAll.ToList());
            }

        }

======= 程式碼如上 ======================(end)

執行時,自行輸入「URL網址」與「頁數」即可
例如:http://....../控制器名稱/IndexPage/3






如下圖。畫面最底下的「分頁列」也可以套用,
跟以前的寫法一樣,幾乎不需更動。

唯一更動的地方就是上面提到的:「ADO.NET + SQL指令」改成「LINQ」











2015年4月17日 星期五

[讀書心得]資料分頁的最佳化,以SQL 2012的 OFFSET-FETCH為例

MIS2000 Lab.文章備份(原文出自)

[讀書心得]資料分頁的最佳化,以SQL 2012的 OFFSET-FETCH為例

http://www.dotblogs.com.tw/mis2000lab/archive/2015/04/10/sql_querying_paging_offset-fetch.aspx


這篇文章源自微軟出版社(Microsoft Press)
2015年的新書 -- T-SQL Querying

T-SQL Querying
  • Published 3/6/2015
  • 1st Edition
  • 864 pages
  • Book 978-0-7356-8504-8
  • eBook 978-0-13-398664-8



微軟網站已經公開了 這一章 的全文,請看


第二頁裡面 介紹資料庫分頁的SQL指令,
包含 TOP、ROW_NUMBER(SQL 2005 起可用)、OFFSET-FETCH(SQL 2012 起可用)

因為我們公司都改成SQL 2012版了,所以我只摘錄 OFFSET-FETCH的部分

====================================================================
SQL 2012起 多了OFFSET-FETCH的作法,
比起上述的TOP、ROW_NUMBER更簡單而且更強。
底下是一般的作法(尚未最佳化),跟前面章節的範例雷同:
-- 註解:改良後的預存程序(尚未最佳化)。
CREATE PROC dbo.GetPage5
  @pagenum  AS BIGINT = 1,
  @pagesize  AS BIGINT = 25
AS
SELECT orderid, orderdate, custid, empid
FROM dbo.Orders
ORDER BY orderid
OFFSET (@pagenum - 1) * @pagesize ROWS FETCH NEXT @pagesize ROWS ONLY;
GO
-- 註解:執行這一段預存程序。
EXEC dbo.GetPage5 @pagenum = 1, @pagesize = 25;
EXEC dbo.GetPage5 @pagenum = 2, @pagesize = 25;
EXEC dbo.GetPage5 @pagenum = 3, @pagesize = 25;
下圖是簡單的解說,讓您瞭解 OFFSET-FECTCH的用法
我們可以進一步修正如下,讓搜尋的效能更好。
根據微軟出版書籍所做的測試,在您閱覽第一千頁的資料時,下面的寫法只需邏輯讀取241次,
而上述的寫法卻要76,644次,效能大幅提昇了。
-- 註解:改良後的預存程序(最佳化)。
CREATE PROC dbo.GetPage6
  @pagenum  AS BIGINT = 1,
  @pagesize  AS BIGINT = 25
AS
WITH K AS   -- Define a table expression based on this query (call it K, for keys).
(
  SELECT orderid
  FROM dbo.Orders
  ORDER BY orderid
  OFFSET (@pagenum - 1) * @pagesize ROWS FETCH NEXT @pagesize ROWS ONLY
)
SELECT O.orderid, O.orderdate, O.custid, O.empid
FROM dbo.Orders AS O
  INNER JOIN K
    ON O.orderid = K.orderid
ORDER BY O.orderid;
GO
-- 註解:執行這一段預存程序。
EXEC dbo.GetPage6 @pagenum = 3, @pagesize = 25;

====================================================================
如果您想進一步瞭解裡面的原理
就直接看微軟公開的這一章吧,
共有六頁,寫得很詳盡!
本站已發表的相關文章 -- 

Model Binding入門、簡介、初試身手 #2 -- Web Form分頁與 IQueryable (不使用EF)



ASP.NET課程 / ASP.NET教學,請看
    http://www.dotblogs.com.tw/mis2000lab/archive/2011/06/24/29807.aspx

    [台北] ASP.NET入門實戰 + ADO.NET進階【二合一】49 hr


ASP.NET影片、遠距教學,請看:
    http://www.dotblogs.com.tw/mis2000lab/archive/2015/03/09/aspnet-online-learning-distance-education-2015.aspx

    [遠距教學、教學影片] ASP.NET (Web Form) 六週課程 上線了!