最近悟出來一個道理,在這兒分享給你們:學歷表明你的過去,能力表明你的如今,學習表明你的未來。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
吃飯嘍,