Khoanglang89
Bạn hãy đăng nhập hoặc đăng ký
Khoanglang89
Bạn hãy đăng nhập hoặc đăng ký
Khoanglang89

NHẬN THIẾT KẾ WEBSITE/ SOFTWARE - LÀM ĐỒ ÁN TỐT NGHIỆP, ĐỒ ÁN CHUYÊN MÔN NGÀNH CÔNG NGHỆ THÔNG TIN


You are not connected. Please login or register

Xem chủ đề cũ hơn Xem chủ đề mới hơn Go down  Thông điệp [Trang 1 trong tổng số 1 trang]

Admin

Admin

Admin
Admin
Loading
The Contoso University sample web application demonstrates how to create ASP.NET MVC 5 applications using the Entity Framework 6 Code First and Visual Studio 2013. For information about the tutorial series, see the first tutorial in the series.

In the previous tutorial you implemented a set of web pages for basic CRUD operations for
Code:
Student
entities. In this tutorial you'll add sorting, filtering, and paging functionality to the Students Index page. You'll also create a page that does simple grouping.

The following illustration shows what the page will look like when you're done. The column headings are links that the user can click to sort by that column. Clicking a column heading repeatedly toggles between ascending and descending sort order.

3_Sorting, Filtering, and Paging with the Entity Framework in an ASP.NET MVC Application StudentPaging

Add Column Sort Links to the Students Index Page


To add sorting to the Student Index page, you'll change the
Code:
Index
method of the
Code:
Student
controller and add code to the
Code:
Student
Index view.

Add Sorting Functionality to the Index Method


In Controllers\StudentController.cs, replace the
Code:
Index
method with the following code:

public ActionResult 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());
}

This code receives a
Code:
sortOrder
parameter from the query string in the URL. The query string value is provided by ASP.NET MVC as a parameter to the action method. The parameter will be a string that's either "Name" or "Date", optionally followed by an underscore and the string "desc" to specify descending order. The default sort order is ascending.

The first time the Index page is requested, there's no query string. The students are displayed in ascending order by
Code:
LastName
, which is the default as established by the fall-through case in the
Code:
switch
statement. When the user clicks a column heading hyperlink, the appropriate
Code:
sortOrder
value is provided in the query string.

The two
Code:
ViewBag
variables are used so that the view can configure the column heading hyperlinks with the appropriate query string values:

ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";

These are ternary statements. The first one specifies that if the
Code:
sortOrder
parameter is null or empty,
Code:
ViewBag.NameSortParm
should be set to "name_desc"; otherwise, it should be set to an empty string. These two statements enable the view to set the column heading hyperlinks as follows:

[th]Current sort order[/th][th]Last Name Hyperlink[/th][th]Date Hyperlink[/th]
Last Name ascendingdescendingascending
Last Name descendingascendingascending
Date ascendingascendingdescending
Date descendingascendingascending

The method uses LINQ to Entities to specify the column to sort by. The code creates an IQueryable variable before the
Code:
switch
statement, modifies it in the
Code:
switch
statement, and calls the
Code:
ToList
method after the
Code:
switch
statement. When you create and modify
Code:
IQueryable
variables, no query is sent to the database. The query is not executed until you convert the
Code:
IQueryable
object into a collection by calling a method such as
Code:
ToList
. Therefore, this code results in a single query that is not executed until the
Code:
return
View
statement.

As an alternative to writing different LINQ statements for each sort order, you can dynamically create a LINQ statement. For information about dynamic LINQ, see Dynamic LINQ.

Add Column Heading Hyperlinks to the Student Index View


In Views\Student\Index.cshtml, replace the
Code:
<tr>
and
Code:
<th>
elements for the heading row with the highlighted code:


@Html.ActionLink("Create New", "Create")










@foreach (var item in Model) {

This code uses the information in the
Code:
ViewBag
properties to set up hyperlinks with the appropriate query string values.

Run the page and click the Last Name and Enrollment Date column headings to verify that sorting works.

3_Sorting, Filtering, and Paging with the Entity Framework in an ASP.NET MVC Application StudentSort

After you click the Last Name heading, students are displayed in descending last name order.

3_Sorting, Filtering, and Paging with the Entity Framework in an ASP.NET MVC Application StudentSortDesc

Add a Search Box to the Students Index Page


To add filtering to the Students Index page, you'll add a text box and a submit button to the view and make corresponding changes in the
Code:
Index
method. The text box will let you enter a string to search for in the first name and last name fields.

Add Filtering Functionality to the Index Method


In Controllers\StudentController.cs, replace the
Code:
Index
method with the following code (the changes are highlighted):

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.Contains(searchString)
|| s.FirstMidName.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.LastName);
break;
}

return View(students.ToList());
}

You've added a
Code:
searchString
parameter to the
Code:
Index
method. The search string value is received from a text box that you'll add to the Index view. You've also added to the LINQ statement a
Code:
where
clause that selects only students whose first name or last name contains the search string. The statement that adds the where clause is executed only if there's a value to search for.


Note In many cases you can call the same method either on an Entity Framework entity set or as an extension method on an in-memory collection. The results are normally the same but in some cases may be different.
For example, the .NET Framework implementation of the
Code:
Contains
method returns all rows when you pass an empty string to it, but the Entity Framework provider for SQL Server Compact 4.0 returns zero rows for empty strings. Therefore the code in the example (putting the
Code:
Where
statement inside an
Code:
if
statement) makes sure that you get the same results for all versions of SQL Server. Also, the .NET Framework implementation of the
Code:

   Contains
method performs a case-sensitive comparison by default, but Entity Framework SQL Server providers perform case-insensitive comparisons by default. Therefore, calling the
Code:
ToUpper
method to make the test explicitly case-insensitive ensures that results do not change when you change the code later to use a repository, which will return an
Code:
IEnumerable
collection instead of an
Code:
IQueryable
object. (When you call the
Code:
Contains
method on an
Code:
IEnumerable
collection, you get the .NET Framework implementation; when you call it on an
Code:
IQueryable
object, you get the database provider implementation.)
Null handling may also be different for different database providers or when you use an
Code:
IQueryable
object compared to when you use an
Code:
IEnumerable
collection. For example, in some scenarios a
Code:
Where
condition such as
Code:

   table.Column != 0
may not return columns that have
Code:
null
as the value. For more information, see Incorrect handling of null variables in 'where' clause.

Add a Search Box to the Student Index View


In Views\Student\Index.cshtml, add the highlighted code immediately before the opening
Code:
table
tag in order to create a caption, a text box, and a Search button.


@Html.ActionLink("Create New", "Create")



@using (Html.BeginForm())
{


Find by name: @Html.TextBox("SearchString")


}


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

@Html.ActionLink("Enrollment Date", "Index", new { sortOrder = ViewBag.DateSortParm })



Run the page, enter a search string, and click Search to verify that filtering is working.

3_Sorting, Filtering, and Paging with the Entity Framework in an ASP.NET MVC Application StudentFilter

Notice the URL doesn't contain the "an" search string, which means that if you bookmark this page, you won't get the filtered list when you use the bookmark. You'll change the Search button to use query strings for filter criteria later in the tutorial.

Add Paging to the Students Index Page


To add paging to the Students Index page, you'll start by installing the PagedList.Mvc NuGet package. Then you'll make additional changes in the
Code:
Index
method and add paging links to the
Code:
Index
view. PagedList.Mvc is one of many good paging and sorting packages for ASP.NET MVC, and its use here is intended only as an example, not as a recommendation for it over other options. The following illustration shows the paging links.

3_Sorting, Filtering, and Paging with the Entity Framework in an ASP.NET MVC Application StudentPaging

Install the PagedList.MVC NuGet Package


The NuGet PagedList.Mvc package automatically installs the PagedList package as a dependency. The PagedList package installs a
Code:
PagedList
collection type and extension methods for
Code:
IQueryable
and
Code:
IEnumerable
collections. The extension methods create a single page of data in a
Code:
PagedList
collection out of your
Code:
IQueryable
or
Code:
IEnumerable
, and the
Code:
PagedList
collection provides several properties and methods that facilitate paging. The PagedList.Mvc package installs a paging helper that displays the paging buttons.

From the Tools menu, select Library Package Manager and then Package Manager Console.

In the Package Manager Console window, make sure ghe Package source is nuget.org and the Default project is ContosoUniversity, and then enter the following command:

Code:
Install-Package PagedList.Mvc

3_Sorting, Filtering, and Paging with the Entity Framework in an ASP.NET MVC Application InstallPagedList

Build the project.

Add Paging Functionality to the Index Method


In Controllers\StudentController.cs, add a
Code:
using
statement for the
Code:
PagedList
namespace:

using PagedList;

Replace the
Code:
Index
method with the following code:

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 (searchString != null)
{
page = 1;
}
else
{
searchString = currentFilter;
}

ViewBag.CurrentFilter = searchString;

var students = from s in db.Students
select s;
if (!String.IsNullOrEmpty(searchString))
{
students = students.Where(s => s.LastName.Contains(searchString)
|| s.FirstMidName.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: // Name ascending
students = students.OrderBy(s => s.LastName);
break;
}

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

This code adds a
Code:
page
parameter, a current sort order parameter, and a current filter parameter to the method signature:

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

The first time the page is displayed, or if the user hasn't clicked a paging or sorting link, all the parameters will be null.  If a paging link is clicked, the
Code:
page
variable will contain the page number to display.

Code:
A ViewBag
property provides the view with the current sort order, because this must be included in the paging links in order to keep the sort order the same while paging:

ViewBag.CurrentSort = sortOrder;

Another property,
Code:
ViewBag.CurrentFilter
, provides the view with the current filter string. This value must be included in the paging links in order to maintain the filter settings during paging, and it must be restored to the text box when the page is redisplayed. If the search string is changed during paging, the page has to be reset to 1, because the new filter can result in different data to display. The search string is changed when a value is entered in the text box and the submit button is pressed. In that case, the
Code:
searchString
parameter is not null.

if (searchString != null)
{
page = 1;
}
else
{
searchString = currentFilter;
}

At the end of the method, the
Code:
ToPagedList
extension method on the students
Code:
IQueryable
object converts the student query to a single page of students in a collection type that supports paging. That single page of students is then passed to the view:

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

The
Code:
ToPagedList
method takes a page number. The two question marks represent the null-coalescing operator. The null-coalescing operator defines a default value for a nullable type; the expression
Code:
(page ?? 1)
means return the value of
Code:
page
if it has a value, or return 1 if
Code:
page
is null.

Add Paging Links to the Student Index View


In Views\Student\Index.cshtml, replace the existing code with the following code. the changes are highlighted.

@model PagedList.IPagedList
@using PagedList.Mvc;


@{
ViewBag.Title = "Students";
}

Students




@Html.ActionLink("Create New", "Create")


@using (Html.BeginForm("Index", "Student", FormMethod.Get))
{


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


}









@foreach (var item in Model) {






}


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

First Name

@Html.ActionLink("Enrollment Date", "Index", new { sortOrder = ViewBag.DateSortParm, currentFilter=ViewBag.CurrentFilter })

@Html.DisplayFor(modelItem => item.LastName)

@Html.DisplayFor(modelItem => item.FirstMidName)

@Html.DisplayFor(modelItem => item.EnrollmentDate)

@Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
@Html.ActionLink("Details", "Details", new { id=item.ID }) |
@Html.ActionLink("Delete", "Delete", new { id=item.ID })


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

@Html.PagedListPager(Model, page => Url.Action("Index",
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))


The
Code:
@model
statement at the top of the page specifies that the view now gets a
Code:
PagedList
object instead of a
Code:
List
object.

The 
Code:
using
statement for
Code:
PagedList.Mvc
gives access to the MVC helper for the paging buttons. 

The code uses an overload of BeginForm that allows it to specify FormMethod.Get.

@using (Html.BeginForm("Index", "Student", FormMethod.Get))
{


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




The default BeginForm submits form data with a POST, which means that parameters are passed in the HTTP message body and not in the URL as query strings. When you specify HTTP GET, the form data is passed in the URL as query strings, which enables users to bookmark the URL. The W3C guidelines for the use of HTTP GET recommend that you should use GET when the action does not result in an update.

The text box is initialized with the current search string so when you click a new page you can see the current search string.

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

The column header links use the query string to pass the current search string to the controller so that the user can sort within filter results:

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

The current page and total number of pages are displayed.

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

If there are no pages to display, "Page 0 of 0" is shown. (In that case the page number is greater than the page count because
Code:
Model.PageNumber
is 1, and
Code:
Model.PageCount
is 0.)

The paging buttons are displayed by the
Code:
PagedListPager
helper:

@Html.PagedListPager( Model, page => Url.Action("Index", new { page }) )

The
Code:
PagedListPager
helper provides a number of options that you can customize, including URLs and styling.  For more information, see TroyGoode  / PagedList on the GitHub site.

Run the page.

3_Sorting, Filtering, and Paging with the Entity Framework in an ASP.NET MVC Application StudentPaging

Click the paging links in different sort orders to make sure paging works. Then enter a search string and try paging again to verify that paging also works correctly with sorting and filtering.

3_Sorting, Filtering, and Paging with the Entity Framework in an ASP.NET MVC Application StudentPagingSearch

Create an About Page That Shows Student Statistics


For the Contoso University website's About page, you'll display how many students have enrolled for each enrollment date. This requires grouping and simple calculations on the groups. To accomplish this, you'll do the following:


  • Create a view model class for the data that you need to pass to the view.
  • Modify the
    Code:
    About
    method in the
    Code:
    Home
    controller.
  • Modify the
    Code:
    About
    view.


Create the View Model


Create a ViewModels folder in the project folder. In that folder, add a class file EnrollmentDateGroup.cs and replace the template code with the following code:

using System;
using System.ComponentModel.DataAnnotations;

namespace ContosoUniversity.ViewModels
{
public class EnrollmentDateGroup
{
[DataType(DataType.Date)]
public DateTime? EnrollmentDate { get; set; }

public int StudentCount { get; set; }
}
}

Modify the Home Controller


In HomeController.cs, add the following
Code:
using
statements at the top of the file:

using ContosoUniversity.DAL;
using ContosoUniversity.ViewModels;

Add a class variable for the database context immediately after the opening curly brace for the class:

public class HomeController : Controller
{
private SchoolContext db = new SchoolContext();

Replace the
Code:
About
method with the following code:

public ActionResult About()
{
IQueryable 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.ToList());
}

The LINQ statement groups the student entities by enrollment date, calculates the number of entities in each group, and stores the results in a collection of
Code:
EnrollmentDateGroup
view model objects.

Add a
Code:
Dispose
method:

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

Modify the About View


Replace the code in the Views\Home\About.cshtml file with the following code:

@model IEnumerable

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

Student Body Statistics









@foreach (var item in Model) {




}

Enrollment Date

Students

@Html.DisplayFor(modelItem => item.EnrollmentDate)

@item.StudentCount

Run the app and click the About link. The count of students for each enrollment date is displayed in a table.

3_Sorting, Filtering, and Paging with the Entity Framework in an ASP.NET MVC Application About

Summary


In this tutorial you've seen how to create a data model and implement basic CRUD, sorting, filtering, paging, and grouping functionality. In the next tutorial you'll begin looking at more advanced topics by expanding the data model.

Please leave feedback on how you liked this tutorial and what we could improve. You can also request new topics at Show Me How With Code.

Links to other Entity Framework resources can be found in ASP.NET Data Access - Recommended Resources.

This article was originally created on February 14, 2014

https://khoanglang89.forumvi.com

Xem chủ đề cũ hơn Xem chủ đề mới hơn Về Đầu Trang  Thông điệp [Trang 1 trong tổng số 1 trang]

Bài viết mới cùng chuyên mục

      Permissions in this forum:
      Bạn không có quyền trả lời bài viết