上篇文章 已經作出了基本的增刪改查 但這遠遠不足以應付實際的項目 今天講下實際項目中 確定會有的 排序 刷選 以及分頁。 重點想多寫點分頁的 畢竟這個是任什麼時候候都要有的html
並且 我會盡可能把這個分頁作的複雜下 這樣到實際項目時 能夠複製過來改改就好了~~ (這裏我用的是國產的基於ScottGu的PagedList<T>類和相關方法完善的分頁--MVCPager)web
是個開源的 帶不少demo介紹的分頁幫助類 這裏說下 建議你們看下源碼 這樣才能進步 要否則只是個會使用插件的人~ 在這裏感謝下做者 ~~ 好了 開始先上效果圖sql
這個樣式能夠調~~ 個人樣子難看了些~~ 顯示當前頁的索引 記錄條數 還有跳轉頁數 等 經常使用分頁的功能都有了mvc
咱們能夠根據姓名查找 能夠點擊 lastName 按姓名排序 和按發佈日期排序 這就是今天要作的~app
一.排序框架
public ViewResult Index(string sortOrder)
{
ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "Name desc" : "";
ViewBag.DateSortParm = sortOrder == "Date" ? "Date desc" : "Date";
var students = from s in db.Students
select s;
switch (sortOrder)
{
case "Name desc":
students = students.OrderByDescending(s => s.LastName);
break;
case "Date":
students = students.OrderBy(s => s.EnrollmentDate);
break;
case "Date desc":
students = students.OrderByDescending(s => s.EnrollmentDate);
break;
default:
students = students.OrderBy(s => s.EnrollmentDate);
break;
}
return View(students.ToList());
}
這亂七八糟的是什麼呢 我來解釋下~ 接受的參數sortOrder是根據什麼排序 例如http://localhost:2175/Student?sortOrder=Date 就是根據時間升序排列
asp.net
咱們能夠先不看前兩行 先看後面的spa
var students = from s in db.Students
select s;
switch (sortOrder)
{
case "Name desc":
students = students.OrderByDescending(s => s.LastName);
break;
case "Date":
students = students.OrderBy(s => s.EnrollmentDate);
break;
case "Date desc":
students = students.OrderByDescending(s => s.EnrollmentDate);
break;
default:
students = students.OrderBy(s => s.EnrollmentDate);
break;
}
先來講下 這不是把全部記錄都查出來 而後再排序 由於這個是IQueryable 的 這個是將表達式樹 翻譯成SQL 最後再執行的 因此在後面的 根據條件刷選 分頁 排序等 是不會有效率問題的 可是若是你把上面的students.tolist() 一下 則就是所有加載啦~~ 由於再也不是IQueryable接口了~~ 也就是說 他是在tolist時或者說 是在AsEnumerable才執行sql~~
.net
好 回到例子上 由於第一次訪問 sortOrder必定是空的 因此switch到 students = students.OrderBy(s => s.EnrollmentDate); 默認按時間排序插件
這時咱們再來看這兩句
ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "Name desc" : "";
ViewBag.DateSortParm = sortOrder == "Date" ? "Date desc" : "Date";
viewBag MVC3纔有的 利用了.net4.0的 dynamic 特性~ 其實這個和MVC2中的 viewdata使用方法差很少 咱們在這裏 設置 ViewBag.NameSortParm以及ViewBag.DateSortParm 是爲了給view用的 一下子看view就明白了~ 上來因爲sortOrder爲空 因此ViewBag.NameSortParm=Name desc 因爲sortOrder 不等於Date 因此
ViewBag.DateSortParm等於 Date
說白了 以時間排序爲例 就是爲了實現 點排序鏈接時 第一次 升序 再點就變成降序了 再點就變成升序........
不看view 怎麼解釋都迷糊~~ 看view
<tr> <th></th> <th> @Html.ActionLink("Last Name", "Index", new { sortOrder=ViewBag.NameSortParm }) </th> <th> First Name </th> <th> @Html.ActionLink("Enrollment Date", "Index", new { sortOrder=ViewBag.DateSortParm }) </th> </tr>
不明白就本身作下 動動手~~ 調試幾回就明白了~
二.根據條件過濾
這裏咱們作的是根據姓名刷選
咱們先在index視圖下加個搜索框和搜索按鈕
@using (Html.BeginForm())
{
<p>
Find by name: @Html.TextBox("SearchString")
<input type="submit" value="Search" /></p>
}
咱們的控制器更改成
public ViewResult Index(string sortOrder, string searchString)
{
ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "Name desc" : "";
ViewBag.DateSortParm = sortOrder == "Date" ? "Date desc" : "Date";
var students = from s in db.Students
select s;
if (!String.IsNullOrEmpty(searchString))
{
students = students.Where(s => s.LastName.ToUpper().Contains(searchString.ToUpper())
|| s.FirstMidName.ToUpper().Contains(searchString.ToUpper()));
}
switch (sortOrder)
{
case "Name desc":
students = students.OrderByDescending(s => s.LastName);
break;
case "Date":
students = students.OrderBy(s => s.EnrollmentDate);
break;
case "Date desc":
students = students.OrderByDescending(s => s.EnrollmentDate);
break;
default:
students = students.OrderBy(s => s.LastName);
break;
}
return View(students.ToList());
}
Index方法多了個參數 SearchSring 這個參數名字是和 Html.TextBox 裏的name對應着的
而且增長以下代碼
if (!String.IsNullOrEmpty(searchString))
{
students = students.Where(s => s.LastName.ToUpper().Contains(searchString.ToUpper())
|| s.FirstMidName.ToUpper().Contains(searchString.ToUpper()));
}
查看姓名裏是否含有要搜索的
這樣 條件過濾就完成了
可是有個小問題 咱們通常搜索完 文本框保留搜索內容 而不是沒了 因此這裏須要再次借用ViewBag.Filter = searchString; 保存下值
而後視圖改成
<p>Find by Name @Html.TextBox("searchString", ViewBag.Filter as string)</p>
好了 這樣搜索就完了~~接下來 最重要的分頁
三.分頁
接下來是講MVCPager
首先 下去下載例子以及DLL 這裏有個問題 就是下載的dll和mvc3不是很兼容 讓我糾結了好久 要去下載mvc3的實例 而後把裏面的 一個叫作MvcPager的dll找到 添加這個引用就OK了
而後咱們打開view下的config 添加命名空間 這樣可讓你的view都有這個命名空間了~
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="Webdiyer.WebControls.Mvc"/><!--添加這個 -->
</namespaces>
</pages>
</system.web.webPages.razor>
改造咱們的控制器 以下
public ActionResult Index(string sortOrder,string searchString,int? page=1)
{
ViewBag.NameSortParm = string.IsNullOrEmpty(sortOrder) ? "Name desc" : "";
ViewBag.DateSortParm = sortOrder == "Date" ? "Date desc" : "Date";
var students = from s in db.Students
select s;
ViewBag.Filter = searchString;
if (!string.IsNullOrEmpty(searchString))
{
students=students.Where(s => s.FirstMidName.ToUpper().Contains(searchString) || s.LastName.ToUpper().Contains(searchString));
}
switch (sortOrder)
{
case "Name desc":
students = students.OrderByDescending(s => s.LastName);
break;
case "Date":
students = students.OrderBy(s => s.EnrollmentDate);
break;
case "Date desc":
students = students.OrderByDescending(s => s.EnrollmentDate);
break;
default:
students = students.OrderBy(s => s.EnrollmentDate);
break;
}
int pageSize = 2;
int pageIndex = page ?? 1;
return View(students.ToPagedList(pageIndex, pageSize));
}
要記得 pageIndex 從1開始 1表示第一頁
只需簡單的返回
int pageSize = 2;
int pageIndex = page ?? 1;
return View(students.ToPagedList(pageIndex, pageSize));
這樣就OK了 就這麼簡單~~
視圖的model 改成 @model PagedList<ContosoUniversity.Models.Student>
而後分頁的視圖爲
<p>共有 @Model.TotalItemCount 條記錄 @Model.CurrentPageIndex/@Model.TotalPageCount</p>
@Html.Pager(Model, new PagerOptions { PageIndexParameterName = "page", ShowPageIndexBox = true, PageIndexBoxType = PageIndexBoxType.TextBox, PageIndexBoxWrapperFormatString = "請輸入頁數{0}" }, "Default", new { sortOrder = ViewBag.DateSortParm, searchString = ViewBag.Filter })
看 一個要顯示覆雜的分頁 就這麼簡單的完成了
你們必定和我同樣 關心生成的SQL語句怎麼樣 是否靠譜 效率能夠麼 讓咱們監控一下生成的SQL語句吧
這是經過跟蹤獲得的SQL
SELECT TOP (2)
[Extent1].[StudentID] AS [StudentID],
[Extent1].[LastName] AS [LastName],
[Extent1].[FirstMidName] AS [FirstMidName],
[Extent1].[EnrollmentDate] AS [EnrollmentDate]
FROM ( SELECT [Extent1].[StudentID] AS [StudentID], [Extent1].[LastName] AS [LastName], [Extent1].[FirstMidName] AS [FirstMidName], [Extent1].[EnrollmentDate] AS [EnrollmentDate], row_number() OVER (ORDER BY [Extent1].[EnrollmentDate] ASC) AS [row_number]
FROM [dbo].[Student] AS [Extent1]
) AS [Extent1]
WHERE [Extent1].[row_number] > 2
ORDER BY [Extent1].[EnrollmentDate] ASC
利用 row_number() 實現的分頁 ~~
好了 分頁OK了
四.總結
基本的EF操做OK了 合理利用第三方插件 大大提升了開發效率 學會借用 但也要知道原理
EF作爲ORM 框架 就是要處理關係 前面這幾篇 都是簡單的操做 沒有設計關係