EF 之 MVC 排序,查詢,分頁 Sorting, Filtering, and Paging For MVC About EF

   最近悟出來一個道理,在這兒分享給你們:學歷表明你的過去,能力表明你的如今,學習表明你的未來。css

   十年河東十年河西,莫欺少年窮html

   學無止境,精益求精前端

   上篇博客咱們學習了EF CodeFirst增刪改查之‘CRUD’,今兒,咱們來探討下MVC下的EF 排序、查詢、分頁操做程序員

   在此,本人先從分頁提及web

   話說,作過webForm項目的程序員用AspNetPage.DLL作過度頁,作過EasyUI框架的程序員,用JS AJAX請求分頁,那麼,MVC 程序員用什麼進行分頁呢?sql

   固然,MVC程序亦可使用上述方式進行分頁後端

   可是......框架

   原始的分頁咱們要寫大量的代碼,或者還須要使用存儲過程,在此,小弟貼一個分頁的存儲過程<也是一個通用的分頁存儲過程>,貼出這段代碼的目的只有一個:讓你們作一個比較。post

   下面,我僅僅貼出SQL端Proc的代碼學習

複製代碼
GO
/****** 對象:  StoredProcedure [dbo].[ZXL_GetPageData]    腳本日期: 11/26/2016  ******/
SET ANSI_NULLS ON
GO 
 SET QUOTED_IDENTIFIER ON 
 GO



CREATE PROCEDURE [dbo].[ZXL_GetPageData]
(
    @TableName  varchar (500), --要進行分頁的表,也能夠用聯接,如dbo.employee或dbo.employee INNER JOIN dbo.jobs ON (dbo.employee.job_id=dbo.jobs.job_id)
    @Fields  varchar(3000)='*', --表中的字段,可使用*代替
    @OrderField  varchar(500), --要排序的字段
    @sqlWhere varchar(500)=NULL, --WHERE子句
    @pageSize int, --分頁的大小
    @pageIndex int, --要顯示的頁的索引
    @TotalPage int output, --頁的總數
    @RecordCount int output --總記錄數
)
as

begin

    Begin Tran

    Declare @sql nvarchar(4000);
    Declare @totalRecord int; --記錄總數

    if (@sqlWhere IS NULL or @sqlWhere = '') set @sql = 'select @totalRecord = count(*) from ' + @TableName 
    else
       
    
       set @sql = 'select @totalRecord = count(*) from ' + @TableName + ' where ' + @sqlWhere
    --執行sql語句獲得記錄總數
    EXEC sp_executesql @sql,N'@totalRecord int OUTPUT',@totalRecord OUTPUT 
    select @TotalPage=CEILING((@totalRecord+0.0)/@PageSize)
    select @RecordCount=CEILING(@totalRecord)
    --根據特定的排序字段爲爲行分配惟一ROW_NUMBER的順序
    if (@sqlWhere IS NULL or @sqlWhere = '')
       set @sql = 'select * from (select ROW_NUMBER() over(order by ' + @OrderField + ') as rowId,' + @Fields + ' from ' + @TableName
    else
       set @sql = 'select * from (select ROW_NUMBER() over(order by ' + @OrderField + ') as rowId,' + @Fields + ' from ' + @TableName + ' where ' + @SqlWhere
    --確保當前頁的索引在合理的範圍以內

    if @PageIndex<=0 
       Set @pageIndex = 1
    if @pageIndex>@TotalPage
       Set @pageIndex = @TotalPage
    --獲得當前頁在整個結果集中準確的ROW_NUMBER值

    Declare @StartRecord int
    Declare @EndRecord int
    set @StartRecord = (@pageIndex-1)*@PageSize + 1
    set @EndRecord = @StartRecord + @pageSize - 1

    --輸出當前頁中的數據

    set @Sql = @Sql + ') as t' + ' where rowId between ' + Convert(varchar(50),@StartRecord) + ' and ' +   Convert(varchar(50),@EndRecord)

    Exec(@Sql)
    If @@Error <> 0

       Begin
           RollBack Tran
           Return -1
       End
    Else
       Begin
           Commit Tran
           Return @totalRecord
       End    
End
複製代碼

   今天,咱們換個口味,來說述下另一種全新的分頁

   首先,添加NuGet引用,搜索:pagedList

   

   而後,在咱們的Controller中添加:using PagedList;

   若是咱們成功添加了NuGet  PagedList引用,那麼,在咱們的Content文件夾中就會生成一個分頁的CSS文件<嘻嘻,微軟不愧是世界老大哥,技術領先別人一大截,我是愈來愈喜歡微軟了>

   截止到此,準備工做也就基本作好了,下面我從後端和前端進行說明:

   後端代碼以下:

複製代碼
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;
using System.Linq;
using EF_Test.DAL;
using System.Data;
using PagedList;

namespace EF_Test.Controllers
{
    public class HomeController : Controller
    {
        private StudentContext db = new StudentContext();
        /// <summary>
        /// 簡單分頁演示
        /// </summary>
        /// <param name="page">頁碼</param>
        /// <returns></returns>
        public ActionResult Index2(int page = 1)//查詢全部學生數據
        {
            return View(db.Students.OrderBy(item => item.Id).ToPagedList(page, 9));
        }
    }
}
複製代碼

 

   參數Page是從前端發送的,表明頁碼,數字9表明每頁的數量,在分頁的過程當中,咱們必須得使用OrderBy進行排序,不然程序會出錯。

   前端代碼以下:

複製代碼
@model PagedList.IPagedList<EF_Test.DAL.Student>
@using PagedList.Mvc
@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

@section css{
    <link href="~/Content/PagedList.css" rel="stylesheet" />
    <style type="text/css">
        body {
            font-size: 12px;
            font-family: "微軟雅黑";
            color: #555;
            position: relative;
            background: #fff;
        }

        a {
            text-decoration: none;
            color: #555;
        }

        #tbList {
            border: 1px solid none;
            width: 800px;
            margin: 10px auto;
            border-collapse: collapse;
        }

            #tbList th, td {
                border: 1px solid #ccc;
                padding: 5px;
                text-align: center;
            }

        tfoot tr td {
            border: none;
        }
    </style>
}

@using (Html.BeginForm("Index", "Home", FormMethod.Get))
{
    <div style="text-align: center;">
        <h1>Mvc分頁例子</h1>
        <table id="tbList">

           
            <tbody>
                @if (Model.Count() != 0)
                {  
                    <tr>
                        <th>姓名
                        </th>
                        <th>性別
                        </th>
                        <th>學號
                        </th>
                    </tr>
                    foreach (var item in Model)
                    {   
                    <tr style="text-align: center;">
                        <td>
                            @Html.DisplayFor(modelItem => item.Name)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.Sex)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.StudentNum)
                        </td>
                    </tr>  
                    }

                }
            </tbody>
            <tfoot>
                <tr>
                    <td colspan="5">
                        <div class="">
                            @if (Model != null)
                            {  
                                <span style="height: 20px; line-height: 20px;">共 @Model.TotalItemCount.ToString() 條記錄,當前第 @Model.PageNumber 頁/共 @Model.PageCount 頁 </span>  
                                @Html.PagedListPager(Model, page => Url.Action("Index", new { page }), new PagedListRenderOptions() { LinkToFirstPageFormat = "首頁", LinkToNextPageFormat = "下一頁", LinkToPreviousPageFormat = "上一頁", LinkToLastPageFormat = "末頁", DisplayItemSliceAndTotal = false, MaximumPageNumbersToDisplay = 3 })    
                            }
                        </div>
                    </td>
                </tr>
            </tfoot>
        </table>
    </div>
}
複製代碼

   前端沒什麼好說的,你們本身測試,運行結果以下

   

   至此,MVC分頁也就講完了,下面咱們來探討排序的查詢的問題

   好吧,因爲小弟還沒吃飯,就不做說明了,直接上代碼:

   前端變動以下:

複製代碼
@model PagedList.IPagedList<EF_Test.DAL.Student>
@using PagedList.Mvc

@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

@section css{
    <link href="~/Content/PagedList.css" rel="stylesheet" />
    <style type="text/css">
        body {
            font-size: 12px;
            font-family: "微軟雅黑";
            color: #555;
            position: relative;
            background: #fff;
        }

        a {
            text-decoration: none;
            color: #555;
        }

        #tbList {
            border: 1px solid none;
            width: 800px;
            margin: 10px auto;
            border-collapse: collapse;
        }

            #tbList th, td {
                border: 1px solid #ccc;
                padding: 5px;
                text-align: center;
            }

        tfoot tr td {
            border: none;
        }
    </style>
}

@using (Html.BeginForm("Index", "Home", FormMethod.Get))
{
    <div style="text-align: center;">
        <h1>Mvc分頁例子</h1>
        <table id="tbList">

           
            <tbody>
                @if (Model.Count() != 0)
                {  
                    <tr>
                        <th>姓名
                        </th>
                        <th>性別
                        </th>
                        <th>學號
                        </th>
                    </tr>
                    foreach (var item in Model)
                    {   
                    <tr style="text-align: center;">
                        <td>
                            @Html.DisplayFor(modelItem => item.Name)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.Sex)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.StudentNum)
                        </td>
                    </tr>  
                    }

                }
            </tbody>
            <tfoot>
                <tr>
                    <td colspan="5">
                        <div class="">
                            @if (Model != null)
                            {  
                                <span style="height: 20px; line-height: 20px;">共 @Model.TotalItemCount.ToString() 條記錄,當前第 @Model.PageNumber 頁/共 @Model.PageCount 頁 </span>  
                                @Html.PagedListPager(Model, page => Url.Action("Index", new { page }), new PagedListRenderOptions() { LinkToFirstPageFormat = "首頁", LinkToNextPageFormat = "下一頁", LinkToPreviousPageFormat = "上一頁", LinkToLastPageFormat = "末頁", DisplayItemSliceAndTotal = false, MaximumPageNumbersToDisplay = 3 })    
                            }
                        </div>
                    </td>
                </tr>
            </tfoot>
        </table>
    </div>
}
複製代碼

   說明幾點:

   查詢使用的是表單Get請求、

   多加了兩個文本框和一個sumbit按鈕,用做查詢

   姓名和學號作成<A>標籤,用做排序,例如:點擊姓名,按照姓名升序排,再次點擊,按照姓名降序排,同理點擊學號

   後端代碼以下:

複製代碼
       /// <summary>
       /// 查詢 排序 分頁
       /// </summary>
       /// <param name="sortOrder">排序字段 默認Id desc</param>
       /// <param name="stuName">搜索框 學生姓名 模糊查詢</param>
       /// <param name="stuNum">搜索框 學生學號 精確查詢</param>
       /// <param name="page">頁碼</param>
       /// <returns></returns>
        public ActionResult Index(string sortOrder, string stuName, string stuNum, int page = 1)//查詢全部學生數據
        {
            //初始化排序-默認排序
            ViewBag.NameSortParm = "NameAsc";
            ViewBag.StumSortParm = "StumAsc";
            //根據click 更改排序
            if (!string.IsNullOrEmpty(sortOrder))
            {
                if (sortOrder.Contains("Name"))
                {
                    if (sortOrder.Equals("NameAsc"))
                    {
                        sortOrder = "NameDesc";
                        ViewBag.NameSortParm = sortOrder;
                    }
                    else
                    {
                        sortOrder = "NameAsc";
                        ViewBag.NameSortParm = sortOrder;
                    }
                }
                if (sortOrder.Contains("Stum"))
                {
                    if (sortOrder.Equals("StumAsc"))
                    {
                        sortOrder = "StumDesc";
                        ViewBag.StumSortParm = sortOrder;
                    }
                    else
                    {
                        sortOrder = "StumAsc";
                        ViewBag.StumSortParm = sortOrder;
                    }
                }
            }
            //}
            //查詢所有數據
            var students = from s in db.Students
                           select s;
            //根據查詢條件檢索
            if (!string.IsNullOrEmpty(stuName))
            {
                //根據姓名模糊查詢
                students = students.Where(s => s.Name.Contains(stuName));
            }
            if (!string.IsNullOrEmpty(stuNum))
            {
                //根據學號精確查詢
                students = students.Where(s => s.StudentNum==stuName);
            }
            //排序處理
            switch (sortOrder)
            {
                case "NameDesc":
                    students = students.OrderByDescending(item=>item.Name);
                    break;
                case "NameAsc":
                    students = students.OrderBy(item => item.Name);
                    break;
                case "StumAsc":
                    students = students.OrderBy(s => s.StudentNum);
                    break;
                case "StumDesc":
                    students = students.OrderByDescending(s => s.StudentNum);
                    break;
                default:
                    students = students.OrderByDescending(s => s.Id);
                    break;
            }
            return View(students.ToPagedList(page, 9));//
        }
複製代碼

   運行結果:

   默認排序:ID 倒序排列

   

   點擊姓名,按照姓名倒序排列,以下:

   再次點擊姓名,按照姓名升序排列、

   同理,點擊學號,不作演示

   輸入姓名,進行模糊查詢

   同理,輸入學號進行精確查詢,不作演示!

   可是這種方式有個最大的弊端,就是每次都必須查詢全部數據,當數據表數據不少時,例若有100W條記錄,那麼這種方式相率會很是低下。解決方法請參考個人博客:http://www.cnblogs.com/chenwolong/p/6913915.html

   吃飯嘍,

相關文章
相關標籤/搜索