久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

翻譯:Contoso 大學(xué) - 3 - 排序、過濾及分頁

 昵稱10504424 2013-12-26

Contoso 大學(xué) - 使用 EF Code First 創(chuàng)建 MVC 應(yīng)用

原文地址:http://www./mvc/tutorials/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application

在上一個課程中,,我們已經(jīng)學(xué)習(xí)了如何使用 EF 對 Student 實(shí)體進(jìn)行增,、刪、改,、查處理,。這次的課程我們將對學(xué)生的 Index 頁面加入排序、過濾以及分頁的功能,。還要創(chuàng)建一個頁面完成簡單的分組,。

下面的截圖展示了完成之后的頁面,列的標(biāo)題作為鏈接支持用戶通過點(diǎn)擊完成排序,,點(diǎn)擊標(biāo)題可以在升序和降序之間進(jìn)行切換,。

3-1 在 Students 的 Index 頁面增加列標(biāo)題鏈接

為 Index 頁面增加排序的功能,我們需要修改 Student 控制器的 Index 方法,,還需要為 Student 視圖增加代碼,。

3-1-1 為 Index 方法增加排序功能

打開 Controllers\StudentController.cs,將 Index 方法替換為如下的代碼,。

復(fù)制代碼
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.LastName);
break;
}
return View(students.ToList());
}
復(fù)制代碼

這段代碼從 URL 中接收名為 sortOrder 的參數(shù),,這個參數(shù)由 ASP.NET MVC 作為參數(shù)傳遞給 Action 方法。這個參數(shù)可以是 “Name” 或者 “Date”,, 可能還有一個空格隔開的 desc 來指定降序,。

當(dāng)?shù)谝淮握埱?Index 的時候,,沒有參數(shù),學(xué)生使用 LastName 的升序順序顯示,。這是通過 switchdefault 代碼段指定的,,當(dāng)用戶點(diǎn)擊一個列的標(biāo)題鏈接的時候,合適的 sortOrder 值需要通過查詢字符串傳遞進(jìn)來,。

兩個 ViewBag 變量用來為視圖提供合適的查詢字符串鏈接值,。

ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "Name desc" : "";
ViewBag.DateSortParm = sortOrder == "Date" ? "Date desc" : "Date";

這里使用了條件語句,第一個用來指定當(dāng) sortOrder 參數(shù)為 null 或者空串的時候,, ViewBag.NameSortParm 應(yīng)用被設(shè)置為 Name desc,,其他情況下,應(yīng)該被設(shè)置為空串,。

這里有四種可能,,依賴于當(dāng)前的排序情況:

  • 如果當(dāng)前的排序規(guī)則為 LastName 升序,那么,,LastName 鏈接應(yīng)該設(shè)置為降序,,Enrollment Date 鏈接必須被設(shè)置為按日期升序。
  • 如果當(dāng)前的排序規(guī)則為 LastName 降序,,那么,,LastName 鏈接應(yīng)該設(shè)置為升序,排序串應(yīng)該為空串,,日期為升序,。
  • 如果當(dāng)前排序的規(guī)則為 Date 升序,那么,,鏈接應(yīng)該為 LastName 升序和日期升序,。
  • 如果當(dāng)前的排序規(guī)則為 Date 降序,那么,,鏈接應(yīng)該為 LastName 升序和日期降序,。

方法中使用 LINQ to Entities 來指定排序,在 switch 之前,,代碼首先創(chuàng)建一個 IQueryable 變量,,在 switch 語句中修改這個查詢表達(dá)式,最后調(diào)用 ToList 方法,。在創(chuàng)建和修改查詢表達(dá)式 IQueryable 的時候,,并沒有將查詢發(fā)送到數(shù)據(jù)庫中執(zhí)行,查詢直到將 IQueryable 對象駝工調(diào)用類似 ToList 方法轉(zhuǎn)換到集合對象的時候才會執(zhí)行,,因此,,代碼中查詢直到最后的 return View 才會被執(zhí)行。

3-2-2 為 Index 視圖增加列標(biāo)題鏈接

Views\Student\Index.cshtml,,使用如下的代碼替換標(biāo)題行中的 <tr> 和 <th> 元素,。

復(fù)制代碼
<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>
復(fù)制代碼

這段代碼使用 ViewBag 屬性來設(shè)置超級鏈接中包含適當(dāng)?shù)牟樵冏址?/p>

運(yùn)行頁面,,點(diǎn)擊列標(biāo)題,來驗(yàn)證排序是否正常,。

3-2 為 Index 頁面增加搜索框

為 Index 頁面增加過濾功能,,需要增加一個文本框和一個提交按鈕,然后,,對 Index 方法進(jìn)行一些修改,文本框允許你輸入一個搜索字符串,,用來在 FirstName 和 LastName 中進(jìn)行搜索,。

3-2-1 為 Index 方法增加過濾功能

打開 Controllers\StudentController.cs 文件,使用下面的代碼替換 Index 方法,。

復(fù)制代碼
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());
}
復(fù)制代碼

現(xiàn)在,,為 Index 方法增加了一個參數(shù) searchString ,LINQ 語句中也增加了一個 where 子句,,用來選擇在 FirstName 或者 LastName 中包含過濾字符串的學(xué)生,。搜索串來自文本框的輸入,后面需要你在視圖中加入它,。增加的 where 條件子句僅僅在提供了搜索串的情況下才會被處理,。

if (!String.IsNullOrEmpty(searchString))
{
students = students.Where(s => s.LastName.ToUpper().Contains(searchString.ToUpper())
|| s.FirstMidName.ToUpper().Contains(searchString.ToUpper()));
}

注意:在傳遞一個空串的時候,.NET 實(shí)現(xiàn)的 Contains 方法將會返回所有的數(shù)據(jù)行,,但是 EF Provider for SQL Server Compact 4.0 對于空串不返回任何行,。因此,代碼中增加了一個 if 判斷語句,,以確保對于所有的 SQL Server 都有一致的處理結(jié)果,。另外,.NET 實(shí)現(xiàn)的 Contains 默認(rèn)進(jìn)行區(qū)分大小寫的字符串比較,,因此,,通過調(diào)用 ToUpper 方法顯式轉(zhuǎn)換字符串為大寫,

以確保在轉(zhuǎn)換到使用資源庫模式的時候不需要修改代碼,。那個時候?qū)祷匾粋€ IEnumerable 集合而不是 IQueryable 對象 ( 在調(diào)用 IEnumerable 集合上的 Contains 方法的時候,,使用 .NET 實(shí)現(xiàn)的方法,在調(diào)用 IQueryable 對象上的 Contains 方法的時候,,使用數(shù)據(jù)庫 Provider 提供的實(shí)現(xiàn) ),。

3-2-2 在 Student 視圖上加入搜索框

在視圖 Views\Student\Index.cshtml 上,table 開始標(biāo)記之前,,增加一個標(biāo)題,,一個文本框,以及一個 Search 按鈕,。

@using (Html.BeginForm())
{
<p>
Find by name: @Html.TextBox("SearchString")
<input type="submit" value="Search" /></p>
}

運(yùn)行程序,,輸入一個搜索串,,然后點(diǎn)擊 Search 按鈕來查看過濾的效果。



3-3 在 Student 的 Index 視圖上增加分頁

為了支持分頁,,你需要通過 NuGet 包管理器安裝 PagedList ,,然后,需要在 Index 方法中增加一些代碼,,在視圖中增加分頁的鏈接,,下面的截圖展示了分頁的鏈接。

3-3-1 安裝 PagedList 包

NuGet 中的 PagedList 包將會增加一種類型:PagedList,,當(dāng)將查詢結(jié)果傳入到 PagedList 中后,,它提供的一系列屬性和方法使得排序更加簡單。

在 Visual Studio 中,,確信選中了當(dāng)前的項(xiàng)目,,而不是解決方案。在 Tools 菜單中,,選擇 Library Package Manager,,然后選擇 Add Library Package Reference。

在 Add Library Package Reference 對話框中,,點(diǎn)擊左邊的 Online 窗格,,然后在搜索框中輸入 pagedlist ,在看到 PagedList 包之后,,點(diǎn)擊 Install,。

3-3-2 為 Index 方法增加分頁功能

打開 Controllers\StudentController.cs,在代碼的前面為 PagedList 命名空間增加 using 語句.

using PagedList;

將 Index 方法替換成如下的代碼,。

復(fù)制代碼
 public ViewResult Index(string sortOrder, string currentFilter, string searchString, int? page)
{
ViewBag.CurrentSort = sortOrder;
ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "Name desc" : "";
ViewBag.DateSortParm = sortOrder == "Date" ? "Date desc" : "Date";

if (Request.HttpMethod == "GET")
{
searchString = currentFilter;
}
else
{
page = 1;
}
ViewBag.CurrentFilter = searchString;

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;
}

int pageSize = 3;
int pageNumber = (page ?? 1);
return View(students.ToPagedList(pageNumber, pageSize));
}
復(fù)制代碼

方法又增加了一個 page 參數(shù),,方法的簽名如下所示。

public ViewResult Index(string sortOrder, string currentFilter, string searchString, int? page)

當(dāng)?shù)谝淮物@式這個頁面的時候,,或者用戶沒有點(diǎn)擊分頁鏈接的時候,,page 參數(shù)將會是 null。如果分頁鏈接被點(diǎn)擊了,,page 參數(shù)將會包含需要顯示的頁碼,。

ViewBag 中的 CurrentSort 屬性用來提供當(dāng)前的排序順序,它必須被包含到當(dāng)前的分頁鏈接中,,以便在分頁處理過程中保持當(dāng)前的排序規(guī)則,。

ViewBag.CurrentSort = sortOrder;

其它的 ViewBag 屬性為視圖提供當(dāng)前的過濾串,因?yàn)檫@個過濾串在頁面被重新顯示的時候,,必須重新回到文本框中,,另外,這個串也必須包含在分頁鏈接中,,以便在分頁過程中,,保持過濾效果,。最后,如果在分頁的過程中修改了過濾串,,那么頁碼將會回到第一頁,,因?yàn)樾碌倪^濾規(guī)則返回了不同的數(shù)據(jù),很可能原來的頁碼在這時候已經(jīng)不再存在了,。

復(fù)制代碼
if (Request.HttpMethod == "GET")
{
searchString = currentFilter;
}
else
{
page = 1;
}
ViewBag.CurrentFilter = searchString;
復(fù)制代碼

在方法的最后,,查詢學(xué)生的表達(dá)式被轉(zhuǎn)換為 PagedList ,而不再是通常的 List,,這樣傳遞到視圖中的就是支持分頁的集合,,代碼如下:

int pageSize = 3;
int pageNumber = (page ?? 1);
return View(students.ToPagedList(pageNumber, pageSize));

ToPagedList 方法需要一個頁碼值,兩個問號用來為可空的頁碼提供一個默認(rèn)值,,表達(dá)式 ( page ?? 1 ) 意味著如果 page 有值得話返回這個值,,如果是 null 的話,,返回 1,。

3-3-3 為視圖增加分頁鏈接

Views\Student\Index.cshtml中,使用下面的代碼替換原有代碼,。

復(fù)制代碼
@model PagedList.IPagedList<ContosoUniversity.Models.Student>

@{
ViewBag.Title = "Students";
}

<h2>Students</h2>

<p>
@Html.ActionLink("Create New", "Create")
</p>
@using (Html.BeginForm())
{
<p>
Find by name: @Html.TextBox("SearchString", ViewBag.CurrentFilter as string)
<input type="submit" value="Search" /></p>
}
<table>
<tr>
<th></th>
<th>
@Html.ActionLink("Last Name", "Index", new { sortOrder=ViewBag.NameSortParm, currentFilter=ViewBag.CurrentFilter })
</th>
<th>
First Name
</th>
<th>
@Html.ActionLink("Enrollment Date", "Index", new { sortOrder = ViewBag.DateSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
</tr>

@foreach (var item in Model) {
<tr>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.StudentID }) |
@Html.ActionLink("Details", "Details", new { id=item.StudentID }) |
@Html.ActionLink("Delete", "Delete", new { id=item.StudentID })
</td>
<td>
@Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
@Html.DisplayFor(modelItem => item.FirstMidName)
</td>
<td>
@Html.DisplayFor(modelItem => item.EnrollmentDate)
</td>
</tr>
}

</table>

<div>
Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber)
of @Model.PageCount

@if (Model.HasPreviousPage)
{
@Html.ActionLink("<<", "Index", new { page = 1, sortOrder = ViewBag.CurrentSort, currentFilter=ViewBag.CurrentFilter })
@Html.Raw(" ");
@Html.ActionLink("< Prev", "Index", new { page = Model.PageNumber - 1, sortOrder = ViewBag.CurrentSort, currentFilter=ViewBag.CurrentFilter })
}
else
{
@:<<
@Html.Raw(" ");
@:< Prev
}

@if (Model.HasNextPage)
{
@Html.ActionLink("Next >", "Index", new { page = Model.PageNumber + 1, sortOrder = ViewBag.CurrentSort, currentFilter=ViewBag.CurrentFilter })
@Html.Raw(" ");
@Html.ActionLink(">>", "Index", new { page = Model.PageCount, sortOrder = ViewBag.CurrentSort, currentFilter=ViewBag.CurrentFilter })
}
else
{
@:Next >
@Html.Raw(" ")
@:>>
}
</div>
復(fù)制代碼

視圖最前面的 @model 語句指定現(xiàn)在傳遞到視圖的不再是 List 而是 PagedList ,。

文本框使用當(dāng)前的搜索串進(jìn)行初始化,以便在分頁的時候不會丟失搜索串,。

 Find by name: @Html.TextBox("SearchString", ViewBag.CurrentFilter as string)  

列的標(biāo)題鏈接使用查詢串來傳遞當(dāng)前的搜索串,,以便傳遞給控制器當(dāng)前的搜索和排序。

@Html.ActionLink("Last Name", "Index", new { sortOrder=ViewBag.NameSortParm, currentFilter=ViewBag.CurrentFilter })

在當(dāng)前頁面的最后,,通過一行來顯示分頁的導(dǎo)航 UI,。

Page [current page number] of [total number of pages] << < Prev Next > >>

<< 符號連接到第一頁, < Prev 鏈接到上一頁,,等等,。如果用戶當(dāng)前就在第一頁,那么,,鏈接到第一頁的鏈接就會被禁用,,類似地,如果用戶當(dāng)前在最后一頁,,導(dǎo)航到最后一頁就會被禁用,,每一個分頁鏈接傳遞頁碼以及當(dāng)前的排序串和搜索串到控制器,這使得可以在分頁的同時維護(hù)排序和過濾規(guī)則,。

如果沒有頁可以顯示,,將會顯示 “Page 0 of 0 “,在這種情況下,,頁面數(shù)字就會大于頁數(shù),,因?yàn)?Model.PageNumber 是 1,,但是 Model.PageCount 為 0。

運(yùn)行頁面,。

在不同的排序規(guī)則下,,點(diǎn)擊分頁鏈接,確認(rèn)分頁在正常工作,。然后輸入一個過濾串,,再次點(diǎn)擊分頁的鏈接,確認(rèn)在排序和過濾的同時,,分頁可以正常工作,。

3-4 創(chuàng)建 About 頁面顯示學(xué)生的統(tǒng)計(jì)情況

在 Contoso 大學(xué)網(wǎng)站的 About 頁面,我們希望能夠顯示每個注冊日有多少學(xué)生注冊,。這需要進(jìn)行分組,,然后在每個組上進(jìn)行簡單地計(jì)算,需要完成下列工作:

  • 創(chuàng)建用于傳遞數(shù)據(jù)到視圖的 ViewModel
  • 修改 Home 控制器中的 About 方法
  • 修改 About 視圖

3-4-1 創(chuàng)建 ViewModel

創(chuàng)建 ViewModels 文件夾,,在文件夾中,,創(chuàng)建 EnrollmentDateGroup.cs 類文件,將代碼替換為如下代碼:

復(fù)制代碼
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace ContosoUniversity.ViewModels
{
public class EnrollmentDateGroup
{
[DisplayFormat(DataFormatString = "{0:d}")]
public DateTime? EnrollmentDate { get; set; }

public int StudentCount { get; set; }
}
}
復(fù)制代碼

3-4-2 修改 Home 控制器

增加如下的 using 語句,。

using ContosoUniversity.DAL;
using ContosoUniversity.Models;
using ContosoUniversity.ViewModels;

增加一個數(shù)據(jù)庫上下文變量,。

private SchoolContext db = new SchoolContext();

使用如下的代碼替換 About 方法。

復(fù)制代碼
public ActionResult About()
{
var data = from student in db.Students
group student by student.EnrollmentDate into dateGroup
select new EnrollmentDateGroup()
{
EnrollmentDate = dateGroup.Key,
StudentCount = dateGroup.Count()
};
return View(data);
}
復(fù)制代碼

LINQ 語句通過注冊日期對學(xué)生進(jìn)行分組,,計(jì)算每一組中的實(shí)體數(shù)量,,最后將查詢結(jié)果保存為 EnrollmentDateGroup 對象。

3-4-3 增加 Dispose 方法

protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}

3-4-4 修改 About 視圖

打開 Views\Home\About.cshtml ,,替換為如下代碼,。

復(fù)制代碼
@model IEnumerable<ContosoUniversity.ViewModels.EnrollmentDateGroup>

@{
ViewBag.Title = "Student Body Statistics";
}

<h2>Student Body Statistics</h2>

<table>
<tr>
<th>
Enrollment Date
</th>
<th>
Students
</th>
</tr>

@foreach (var item in Model) {
<tr>
<td>
@String.Format("{0:d}", item.EnrollmentDate)
</td>
<td>
@item.StudentCount
</td>
</tr>
}
</table>
復(fù)制代碼

運(yùn)行頁面,每個注冊日注冊學(xué)生的數(shù)量顯示在表格中,。

現(xiàn)在,,你已經(jīng)看到了如何創(chuàng)建數(shù)據(jù)模型,以及實(shí)現(xiàn)基本的增,、刪,、改、查處理,,排序,、過濾、分頁和分組功能,。下一次,,我們將會擴(kuò)展數(shù)據(jù)模型開始更加高級的內(nèi)容。

分類: EF

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多