使用EF6和MVC5实现一个简单的选课系统--排序、过滤和分页(3/12)
2014-03-24 20:47
961 查看
先贴出来英文的,抽空翻译!
本讲源代码下载
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, seethe
first tutorial in the series.
In the previous tutorial you implemented a set of web pages for basic CRUD operations for
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.
![](http://i3.asp.net/media/4472724/StudentPaging.png?cdn_id=2012-10-31-001)
To add sorting to the Student Index page, you'll change the
of the
view.
In Controllers\StudentController.cs, replace the
with the following code:
This code receives a
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
which is the default as established by the fall-through case in the
When the user clicks a column heading hyperlink, the appropriate
is provided in the query string.
The two
the column heading hyperlinks with the appropriate query string values:
These are ternary statements. The first one specifies that if the
is null or empty,
otherwise, it should be set to an empty string. These two statements enable the view to set the column heading hyperlinks as follows:
The method uses LINQ
to Entities to specify the column to sort by. The code creates an IQueryable variable
before the
and calls the
When you create and modify
to the database. The query is not executed until you convert the
into a collection by calling a method such as
this code results in a single query that is not executed until the
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.
In Views\Student\Index.cshtml, replace the
for the heading row with the highlighted code:
This code uses the information in the
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.
![](http://i1.asp.net/media/48048/StudentSort.png?cdn_id=2012-10-31-001)
After you click the Last Name heading, students are displayed in descending last name order.
![](http://i1.asp.net/media/48049/StudentSortDesc.png?cdn_id=2012-10-31-001)
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
The text box will let you enter a string to search for in the first name and last name fields.
In Controllers\StudentController.cs, replace the
with the following code (the changes are highlighted):
You've added a
You've also added to the LINQ statement a
only students whose first name or last name contains the search string. The search string value is received from a text box that you'll add to the Index view. 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
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
inside an
for all versions of SQL Server. Also, the .NET Framework implementation of the
performs a case-sensitive comparison by default, but Entity Framework SQL Server providers perform case-insensitive comparisons by default. Therefore, calling the
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
instead of an
on an
when you call it on an
provider implementation.)
Null handling may also be different for different database providers or when you use an
compared to when you use an
in some scenarios a
not return columns that have
see Incorrect
handling of null variables in 'where' clause.
In Views\Student\Index.cshtml, add the highlighted code immediately before the opening
in order to create a caption, a text box, and a Search button.
Run the page, enter a search string, and click Search to verify that filtering is working.
![](http://i3.asp.net/media/48045/StudentFilter.png?cdn_id=2012-10-31-001)
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.
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
the
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.
![](http://i3.asp.net/media/4472724/StudentPaging.png?cdn_id=2012-10-31-001)
The NuGet PagedList.Mvc package automatically installs the PagedList package
as a dependency. The PagedListpackage installs a
type and extension methods for
The extension methods create a single page of data in a
out of your
and the
that facilitate paging. ThePagedList.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
projectis ContosoUniversity, and then enter the following command:
![](http://i1.asp.net/media/48016/InstallPagedList.png?cdn_id=2012-10-31-001)
In Controllers\StudentController.cs, add a
for the
Replace the
This code adds a
and a current filter parameter to the method signature:
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
will contain the page number to display.
because this must be included in the paging links in order to keep the sort order the same while paging:
Another property,
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
is not null.
At the end of the method, the
students
page of students in a collection type that supports paging. That single page of students is then passed to the view:
The
represent the null-coalescing
operator. The null-coalescing operator defines a default value for a nullable type; the expression
or return 1 if
In Views\Student\Index.cshtml, replace the existing code with the following code. the changes are highlighted.
The
view now gets a
The
access to the MVC helper for the paging buttons.
The code uses an overload of BeginForm that
allows it to specify FormMethod.Get.
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 GETrecommend 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.
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:
The current page and total number of pages are displayed.
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
1, and
The paging buttons are displayed by the
The
can customize, including URLs and styling. For more information, see TroyGoode
/ PagedList on the GitHub site.
Run the page.
![](http://i3.asp.net/media/4472724/StudentPaging.png?cdn_id=2012-10-31-001)
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.
![](http://i3.asp.net/media/4472730/StudentPagingSearch.png?cdn_id=2012-10-31-001)
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
Modify the
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:
In HomeController.cs, add the following
at the top of the file:
Add a class variable for the database context immediately after the opening curly brace for the class:
Replace the
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
model objects.
Add a
Replace the code in the Views\Home\About.cshtml file with the following code:
Run the app and click the About link. The count of students for each enrollment date is displayed in a table.
![](http://i1.asp.net/media/47994/About.png?cdn_id=2012-10-31-001)
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.
本讲源代码下载
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, seethe
first tutorial in the series.
In the previous tutorial you implemented a set of web pages for basic CRUD operations for
Studententities.
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.
![](http://i3.asp.net/media/4472724/StudentPaging.png?cdn_id=2012-10-31-001)
Add Column Sort Links to the Students Index Page
To add sorting to the Student Index page, you'll change the Indexmethod
of the
Studentcontroller and add code to the
StudentIndex
view.
Add Sorting Functionality to the Index Method
In Controllers\StudentController.cs, replace the Indexmethod
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
sortOrderparameter 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
LastName,
which is the default as established by the fall-through case in the
switchstatement.
When the user clicks a column heading hyperlink, the appropriate
sortOrdervalue
is provided in the query string.
The two
ViewBagvariables 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
sortOrderparameter
is null or empty,
ViewBag.NameSortParmshould 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:
Current sort order | Last Name Hyperlink | Date Hyperlink |
---|---|---|
Last Name ascending | descending | ascending |
Last Name descending | ascending | ascending |
Date ascending | ascending | descending |
Date descending | ascending | ascending |
to Entities to specify the column to sort by. The code creates an IQueryable variable
before the
switchstatement, modifies it in the
switchstatement,
and calls the
ToListmethod after the
switchstatement.
When you create and modify
IQueryablevariables, no query is sent
to the database. The query is not executed until you convert the
IQueryableobject
into a collection by calling a method such as
ToList. Therefore,
this code results in a single query that is not executed until the
return Viewstatement.
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 <tr>and
<th>elements
for the heading row with the highlighted code:
<p> @Html.ActionLink("Create New", "Create") </p> <table> <tr> <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> <th></th> </tr> @foreach (var item in Model) {
This code uses the information in the
ViewBagproperties 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.
![](http://i1.asp.net/media/48048/StudentSort.png?cdn_id=2012-10-31-001)
After you click the Last Name heading, students are displayed in descending last name order.
![](http://i1.asp.net/media/48049/StudentSortDesc.png?cdn_id=2012-10-31-001)
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 Indexmethod.
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 Indexmethod
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.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());
}
You've added a
searchStringparameter to the
Indexmethod.
You've also added to the LINQ statement a
whereclausethat selects
only students whose first name or last name contains the search string. The search string value is received from a text box that you'll add to the Index view. 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
Containsmethod
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
Wherestatement
inside an
ifstatement) makes sure that you get the same results
for all versions of SQL Server. Also, the .NET Framework implementation of the
Containsmethod
performs a case-sensitive comparison by default, but Entity Framework SQL Server providers perform case-insensitive comparisons by default. Therefore, calling the
ToUppermethod
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
IEnumerablecollection
instead of an
IQueryableobject. (When you call the
Containsmethod
on an
IEnumerablecollection, you get the .NET Framework implementation;
when you call it on an
IQueryableobject, you get the database
provider implementation.)
Null handling may also be different for different database providers or when you use an
IQueryableobject
compared to when you use an
IEnumerablecollection. For example,
in some scenarios a
Wherecondition such as
table.Column != 0may
not return columns that have
nullas 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 tabletag
in order to create a caption, a text box, and a Search button.
<p> @Html.ActionLink("Create New", "Create") </p> @using (Html.BeginForm()) { <p> Find by name: @Html.TextBox("SearchString") <input type="submit" value="Search" /></p> } <table> <tr>
Run the page, enter a search string, and click Search to verify that filtering is working.
![](http://i3.asp.net/media/48045/StudentFilter.png?cdn_id=2012-10-31-001)
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 makeadditional changes in the
Indexmethod and add paging links to
the
Indexview. 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.
![](http://i3.asp.net/media/4472724/StudentPaging.png?cdn_id=2012-10-31-001)
Install the PagedList.MVC NuGet Package
The NuGet PagedList.Mvc package automatically installs the PagedList packageas a dependency. The PagedListpackage installs a
PagedListcollection
type and extension methods for
IQueryableand
IEnumerablecollections.
The extension methods create a single page of data in a
PagedListcollection
out of your
IQueryableor
IEnumerable,
and the
PagedListcollection provides several properties and methods
that facilitate paging. ThePagedList.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
projectis ContosoUniversity, and then enter the following command:
Install-Package PagedList.Mvc
![](http://i1.asp.net/media/48016/InstallPagedList.png?cdn_id=2012-10-31-001)
Add Paging Functionality to the Index Method
In Controllers\StudentController.cs, add a usingstatement
for the
PagedListnamespace:
using PagedList;
Replace the
Indexmethod 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.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: // 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
pageparameter, 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
pagevariable
will contain the page number to display.
A ViewBagproperty 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,
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
searchStringparameter
is not null.
if (searchString!= null)
{
page = 1;
}
else
{
searchString= currentFilter;
}
At the end of the method, the
ToPagedListextension method on the
students
IQueryableobject 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
ToPagedListmethod 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
(page ?? 1)means return the value of
pageif it has a value,
or return 1 if
pageis 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<ContosoUniversity.Models.Student> @using PagedList.Mvc; <link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" /> @{ ViewBag.Title = "Students"; } <h2>Students</h2> <p> @Html.ActionLink("Create New", "Create") </p> @using (Html.BeginForm("Index", "Student", FormMethod.Get)) { <p> Find by name: @Html.TextBox("SearchString", ViewBag.CurrentFilter as string) <input type="submit" value="Search" /> </p> } <table class="table"> <tr> <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> <th></th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.LastName) </td> <td> @Html.DisplayFor(modelItem => item.FirstMidName) </td> <td> @Html.DisplayFor(modelItem => item.EnrollmentDate) </td> <td> @Html.ActionLink("Edit", "Edit", new { id=item.ID }) | @Html.ActionLink("Details", "Details", new { id=item.ID }) | @Html.ActionLink("Delete", "Delete", new { id=item.ID }) </td> </tr> } </table> <br /> 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
@modelstatement at the top of the page specifies that the
view now gets a
PagedListobject instead of a
Listobject.
The
usingstatement for
PagedList.Mvcgives
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)) { <p> Find by name: @Html.TextBox("SearchString", ViewBag.CurrentFilter as string) <input type="submit" value="Search" /> </p> }
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 GETrecommend 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
Model.PageNumberis
1, and
Model.PageCountis 0.)
The paging buttons are displayed by the
PagedListPagerhelper:
@Html.PagedListPager( Model, page => Url.Action("Index", new { page }) )
The
PagedListPagerhelper 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.
![](http://i3.asp.net/media/4472724/StudentPaging.png?cdn_id=2012-10-31-001)
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.
![](http://i3.asp.net/media/4472730/StudentPagingSearch.png?cdn_id=2012-10-31-001)
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
Aboutmethod in the
Homecontroller.
Modify the
Aboutview.
Create the View Model
Create a ViewModels folder in the project folder. In that folder, add a class file EnrollmentDateGroup.cs andreplace 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 usingstatements
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
Aboutmethod with the following code:
public ActionResult About() { IQueryable<EnrollmentDateGroup> 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
EnrollmentDateGroupview
model objects.
Add a
Disposemethod:
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<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> @Html.DisplayFor(modelItem => item.EnrollmentDate) </td> <td> @item.StudentCount </td> </tr> } </table>
Run the app and click the About link. The count of students for each enrollment date is displayed in a table.
![](http://i1.asp.net/media/47994/About.png?cdn_id=2012-10-31-001)
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.
相关文章推荐
- 使用EF6和MVC5实现一个简单的选课系统--启航(1/12)
- 使用EF6和MVC5实现一个简单的选课系统--使用EF6实现继承(11/12)
- 使用EF6和MVC5实现一个简单的选课系统--EF6的弹性链接和命令拦截(4/12)
- 使用EF6和MVC5实现一个简单的选课系统--使用EF6实现基本的GRUD功能(2/12)
- 使用EF6和MVC5实现一个简单的选课系统--EF6的代码优先迁移和部署(5/12)
- 使用EF6和MVC5实现一个简单的选课系统--使用EF6读取相关数据(7/12)
- 使用EF6和MVC5实现一个简单的选课系统--使用EF6更新相关数据(8/12)
- 使用EF6和MVC5实现一个简单的选课系统--使用EF6异步编程模式和存储过程(9/12)
- 使用EF6和MVC5实现一个简单的选课系统--使用EF6处理并发操作(10/12)
- 使用EF6和MVC5实现一个简单的选课系统--EF6的高级用法(12/12)
- 一个小型的网站,比如个人网站,可以使用最简单的html静态页面就实现了,配合一些图片达到美化效果,所有的页面均存放在一个目录下,这样的网站对系统架构、性能的要求都很简单,随着互联网业务的不断丰富,网站
- 【分享】分享一个基于SSH实现的简单学生选课系统(附源码)
- 使用Node.js + MongoDB实现一个简单的日志分析系统
- 【分享】分享一个基于SSH实现的简单学生选课系统(附源码)
- Python使用multiprocessing实现一个最简单的分布式作业调度系统
- Python使用multiprocessing实现一个最简单的分布式作业调度系统
- 使用Node.js + MongoDB实现一个简单的日志分析系统
- 使用ICE实现一个简单的文件系统
- 使用Servlet和JSP实现一个简单的Web聊天室系统
- 【EntityFramework系列教程三,翻译】在ASP.NET MVC程序中使用EntityFramework对数据进行排序、过滤筛选以及实现分页