Entity framework сортировка по дате
Далее добавим в проект в папку Models следующие классы User и Company :
Для взаимодействия с MS SQL Server через Entity Framework добавим в проект через Nuget пакет Microsoft.EntityFrameworkCore.SqlServer . Далее добавим в папку Models новый класс UsersContext , через который будем взаимодействовать с бд:
В файле Startup.cs установим контекст данных и подключение к базе данных:
Итак, в классе User есть три свойства (не считая Id), по которым можно вести сортировку: Name, Age, Company. Сортировка может быть по возрастанию и по убыванию. Таким образом, мы получаем шесть критериев сортировки: сортировка по свойству Name по возрастанию, сортировка по свойству Name по убыванию и так далее. Для описания всех этих критериев добавим в папку Models перечисление SortState :
Это перечисление хранит критерии сортировки в виде числовых констант.
Теперь изменим код контроллера HomeController:
Критерий сортировки передается в метод Index в виде параметра sortOrder. Мы ожидаем, что он будет равен одной из констант перечисления SortState. Если никакое значение не передается, по по умолчанию считаем, что используется сортировка по имени по возрастанию: SortState sortOrder = SortState.NameAsc
Далее устанавливаем ряд переменных во ViewData, которые будут хранить значения для трех столбцов. Например, для свойства Name определено значение ViewData["NameSort"] . Если параметр sortOrder равен константе SortState.NameAsc , то ViewData["NameSort"] присваивается значение SortState.NameDesc . То есть если ранее значение ViewData["NameSort"] указывало на сортировку по имени по возрастанию, то теперь после сортировки оно будет указывать на сортировку по имени по убыванию. И наоборот.
Далее в методе в конструкции switch..case смотрит на значение sortOrder и производим сортировку с помощью метода OrderBy/OrderByDescending .
В конце передаем полученные данные в представление.
И определим код в представлении Index.cshtml :
В представлении каждый заголовок столбца будет представлять ссылку. То есть мы нажимаем на столбец, и отправляется запрос на сервер, который выполняет фильтрацию.
Каждая ссылка определена с помощью tag-хелпера:
Атрибут asp-route-sortOrder позволяет задать параметр sortOrder, который будет передавать на сервер выбранный критерий сортировки. И в результате будет создавать ссылка типа следующей:
В итоге весь проект будет выглядеть так:
После запуска проекта с помощью нажатия на заголовки столбцов в таблице мы сможем отсортировать объекты по нужному столбцу:
В предыдущем руководствевы реализовали набор веб-страниц для базовых операций CRUD для Student сущностей. В этом руководстве вы добавите функции сортировки, фильтрации и разбиения на страницы для индекса учащихся . Вы также создадите простую страницу группирования.
На следующем рисунке показано, как будет выглядеть страница после завершения. Заголовки столбцов являются ссылками, при нажатии на которые происходит сортировка по этому столбцу. При повторном нажатии на заголовок происходит переключение между сортировкой по возрастанию и убыванию.
В этом учебнике рассмотрены следующие задачи.
- Добавление ссылок для сортировки столбцов
- Добавление поля поиска
- Добавление разбиения по страницам
- Создание страницы сведений
Дополнительные ресурсы
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:
Добавление разбиения на страницы в метод Index
В контроллерс\студентконтроллер.КСдобавьте using инструкцию для PagedList пространства имен:
Замените метод Index следующим кодом:
Этот код добавляет page параметр, текущий параметр порядка сортировки и текущий параметр фильтра в сигнатуру метода:
При первом отображении страницы или если пользователь не щелкнул ссылку на подкачку или сортировку, все параметры имеют значение null. Если щелкнуть ссылку подкачки, page переменная содержит номер отображаемой страницы.
ViewBag Свойство предоставляет представление с текущим порядком сортировки, поскольку оно должно быть включено в ссылки разбиения на страницы, чтобы порядок сортировки совпадал с порядком разбиения на страницы:
В конце метода ToPagedList метод расширения объекта Students IQueryable преобразует запрос Student на одну страницу учащихся в типе коллекции, который поддерживает разбиение на страницы. После этого одна страница учащихся передается в представление:
Метод ToPagedList принимает номер страницы. Два знака вопроса представляют оператор объединения со значением NULL. Этот оператор определяет значение по умолчанию для значения null; выражение (page ?? 1) возвращает значение переменной page , если она имеет значение, и возвращает 1, если переменная page имеет значение null.
Создание модели представления
Создайте папку ViewModels в папке проекта. В этой папке добавьте файл класса енроллментдатеграуп. CS и замените код шаблона следующим кодом:
Modify the Home Controller
In HomeController.cs, add the following using statements 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 About method with the following code:
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 EnrollmentDateGroup view model objects.
Add a Dispose method:
Добавление ссылок на подкачку в представление индекса учащихся
В виевс\студент\индекс.кштмлзамените существующий код следующим кодом. Изменения выделены.
Оператор @model в начале страницы указывает на то, что теперь представление принимает объект PagedList , а не объект List .
using Инструкция для PagedList.Mvc предоставляет доступ к вспомогательному модулю MVC для кнопок разбиения на страницы.
Код использует перегрузку бегинформ , которая позволяет ему указать форммесод. Get.
Текстовое поле инициализируется текущей строкой поиска, поэтому при щелчке на новой странице можно увидеть текущую строку поиска.
Ссылки в заголовках столбцов передают в контроллер при помощи строки запроса текущее значение строки поиска, чтобы пользователь мог сортировать отфильтрованные данные:
Отобразится текущая страница и общее количество страниц.
Если нет страниц для отображения, отображается страница 0 из 0. (В этом случае номер страницы больше, чем число страниц, так как Model.PageNumber значение равно 1, а Model.PageCount равно 0.)
Вспомогательная функция отображает PagedListPager кнопки разбиения по страницам:
PagedListPager Вспомогательное приложение предоставляет ряд параметров, которые можно настраивать, включая URL-адреса и стили. дополнительные сведения см. в разделе тройгуде/пажедлист на GitHub сайте.
Чтобы убедиться, что постраничный просмотр работает, нажимайте кнопки перелистывания при различном порядке сортировки. Затем введите строку поиска и повторите перелистывание, чтобы убедиться, что разбиение на страницы работает корректно вместе с сортировкой и фильтрацией.
Создание страницы сведений
На странице About веб-сайта "Университет Contoso" будет отображаться количество зачисленных студентов по дням. Для этого понадобится группировка и выполнение простых расчетов в группах. Для выполнения этой задачи нам потребуется следующее:
- Создать класс модели представления для данных, которые необходимо передать в представление.
- About Измените метод в Home контроллере.
- About Измените представление.
Modify the About View
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 displays in a table.
Предварительные требования
Install the PagedList.MVC NuGet package
The NuGet PagedList.Mvc package automatically installs the PagedList package as a dependency. The PagedList package installs a PagedList collection type and extension methods for IQueryable and IEnumerable collections. The extension methods create a single page of data in a PagedList collection out of your IQueryable or IEnumerable , and the 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 NuGet Package Manager and then Package Manager Console.
Build the project.
Add a Search box
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 Index method. The text box lets you enter a string to search for in the first name and last name fields.
Add a search box to the Student index view
In Views\Student\Index.cshtml, add the highlighted code immediately before the opening table tag 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.
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. This applies also to the column sort links, as they will sort the whole list. You'll change the Search button to use query strings for filter criteria later in the tutorial.
Добавление ссылок для сортировки столбцов
Чтобы добавить сортировку на страницу индекса учащихся, измените Index метод Student контроллера и добавьте код в Student представление индекса.
Get the code
Добавление функций фильтрации в метод Index
В контроллерс\студентконтроллер.КСзамените Index метод следующим кодом (изменения выделены):
Код добавляет searchString параметр в Index метод. Значение строки поиска получается из текстового поля, которое мы добавили в представление Index. Он также добавляет where предложение в инструкцию LINQ, которое выбирает только учащихся, чье имя или фамилия содержат строку поиска. Инструкция, которая добавляет Where предложение, выполняется только в том случае, если имеется искомое значение.
Во многих случаях один и тот же метод можно вызвать либо в Entity Framework наборе сущностей, либо в виде метода расширения для коллекции в памяти. Результаты обычно одинаковы, но в некоторых случаях они могут отличаться.
Обработка значений NULL может также отличаться для разных поставщиков баз данных или при использовании IQueryable объекта по сравнению с IEnumerable коллекцией. Например, в некоторых сценариях Where условие, например table.Column != 0 , не может возвращать столбцы, имеющие null значение. по умолчанию EF создает дополнительные операторы SQL, чтобы обеспечить равенство значений null в базе данных, подобной работе в памяти, но можно установить флаг уседатабасенуллсемантикс в EF6 или вызвать метод усерелатионалнуллс в EF Core, чтобы настроить это поведение.
Получите код
Add filtering functionality to the Index method
In Controllers\StudentController.cs, replace the Index method with the following code (the changes are highlighted):
The code adds a searchString parameter to the Index method. The search string value is received from a text box that you'll add to the Index view. It also adds a where clause to the LINQ statement that selects only students whose first name or last name contains the search string. The statement that adds the Where clause executes only if there's a value to search for.
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.
Null handling may also be different for different database providers or when you use an IQueryable object compared to when you use an IEnumerable collection. For example, in some scenarios a Where condition such as table.Column != 0 may not return columns that have null as the value. By default, EF generates additional SQL operators to make equality between null values work in the database like it works in memory, but you can set the UseDatabaseNullSemantics flag in EF6 or call the UseRelationalNulls method in EF Core to configure this behavior.
установка пакета NuGet пажедлист. MVC
пакет NuGet пажедлист. Mvc автоматически устанавливает пакет пажедлист в качестве зависимости. Пакет пажедлист устанавливает PagedList тип коллекции и методы расширения для IQueryable коллекций и IEnumerable . Методы расширения создают одну страницу данных в PagedList коллекции вне IQueryable или IEnumerable , а PagedList Коллекция предоставляет несколько свойств и методов, которые упрощают разбиение на страницы. Пакет пажедлист. MVC устанавливает вспомогательный метод разбиения на страницы, который отображает кнопки разбиения на страницы.
в меню сервис выберите NuGet диспетчер пакетов а затем диспетчер пакетов консоль.
Выполните построение проекта.
Prerequisites
Изменение контроллера Home
В HomeController. CSдобавьте в начало файла следующие using инструкции:
Добавьте переменную класса для контекста базы данных сразу после открывающей фигурной скобки для класса:
Замените метод About следующим кодом:
Запрос LINQ группирует записи из таблицы студентов по дате зачисления, вычисляет число записей в каждой группе и сохраняет результаты в коллекцию объектов моделей представления EnrollmentDateGroup .
Dispose Добавьте метод:
Добавление поля поиска
Чтобы добавить фильтрацию на страницу индекса учащихся, добавьте в представление текстовое поле и кнопку Submit и внесите соответствующие изменения в Index метод. Текстовое поле позволяет ввести строку для поиска в полях Name и Last Name.
Добавление функции сортировки в метод Index
В контроллерс\студентконтроллер.КСзамените Index метод следующим кодом:
Этот код принимает параметр sortOrder из строки запроса в URL. значение строки запроса предоставляется ASP.NET MVC в качестве параметра метода действия. Параметр представляет собой строку, которая имеет значение "Name" или "Date", при необходимости за которой следует символ подчеркивания и строка "DESC" для указания порядка убывания. По умолчанию используется порядок сортировки по возрастанию.
При первом запросе страницы Index строка запроса отсутствует. Студенты отображаются в порядке возрастания по LastName , который является значением по умолчанию, установленным в операторе перебора switch . Когда пользователь щелкает гиперссылку заголовка столбца, в строку запроса подставляется соответствующее значение параметра sortOrder .
Эти две ViewBag переменные используются, чтобы представление могли настроить гиперссылки заголовка столбца с соответствующими значениями строки запроса:
Это тернарные условные операторы. Первый указывает, что если sortOrder параметр имеет значение null или пуст, ViewBag.NameSortParm для него следует задать значение "name_desc"; в противном случае необходимо установить пустую строку. Следующие два оператора устанавливают гиперссылки в заголовках столбцов в представлении следующим образом:
Текущий порядок сортировки | Гиперссылка "Last Name" (Фамилия) | Гиперссылка "Date" (Дата) |
---|---|---|
"Last Name" (Фамилия) по возрастанию | descending | ascending |
"Last Name" (Фамилия) по убыванию | ascending | ascending |
"Date" (Дата) по возрастанию | ascending | descending |
"Date" (Дата) по убыванию | ascending | ascending |
В качестве альтернативы написанию различных операторов LINQ для каждого порядка сортировки можно динамически создать инструкцию LINQ. Дополнительные сведения о динамическом LINQ см. в разделе dynamic LINQ.
Изменение представления About
Замените код в файле виевс\хоме\абаут.кштмл следующим кодом:
Запустите приложение и щелкните ссылку About (о программе ).
Число учащихся для каждой даты регистрации отображается в таблице.
Create an About page
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 About method in the Home controller.
- Modify the About view.
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.
The @model statement at the top of the page specifies that the view now gets a PagedList object instead of a List object.
The using statement for 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.
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 Model.PageNumber is 1, and Model.PageCount is 0.)
The paging buttons are displayed by the PagedListPager helper:
The 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.
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.
Add sorting functionality to the Index method
In Controllers\StudentController.cs, replace the Index method with the following code:
This code receives a 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 is 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 switch statement. When the user clicks a column heading hyperlink, the appropriate sortOrder value is provided in the query string.
The two ViewBag variables are used so that the view can configure the column heading hyperlinks with the appropriate query string values:
These are ternary statements. The first one specifies that if the sortOrder parameter is null or empty, 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:
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 |
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.
Добавление поля поиска в представление индекса учащихся
В виевс\студент\индекс.кштмлДобавьте выделенный код непосредственно перед открывающим table тегом, чтобы создать заголовок, текстовое поле и кнопку поиска .
Запустите страницу, введите строку поиска и нажмите кнопку Поиск , чтобы убедиться, что фильтрация работает.
Обратите внимание, что URL-адрес не содержит строку поиска "a". Это означает, что если вы заметите эту страницу в закладки, отфильтрованный список не будет получен при использовании закладки. Это также относится к ссылкам сортировки столбцов, так как они будут сортировать весь список. Вы измените кнопку поиска , чтобы в дальнейшем использовать строки запросов для критериев фильтрации.
Add paging
Дальнейшие действия
В этом учебнике рассмотрены следующие задачи.
- Добавление ссылок для сортировки столбцов
- Добавление поля поиска
- Добавление разбиения по страницам
- Создание страницы сведений
Перейдите к следующей статье, чтобы узнать, как использовать устойчивость подключений и перехват команд.
In the previous tutorial, you implemented a set of web pages for basic CRUD operations for Student entities. In this tutorial you add sorting, filtering, and paging functionality to the Students Index page. You also create a simple grouping page.
The following image 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.
In this tutorial, you:
- Add column sort links
- Add a Search box
- Add paging
- Create an About page
Add paging functionality to the Index method
In Controllers\StudentController.cs, add a using statement for the PagedList namespace:
Replace the Index method with the following code:
The first time the page is displayed, or if the user hasn't clicked a paging or sorting link, all the parameters are null. If a paging link is clicked, the page variable contains the page number to display.
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:
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 searchString parameter is not null.
At the end of the method, the ToPagedList extension method on the students 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:
The 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 (page ?? 1) means return the value of page if it has a value, or return 1 if page is null.
Add column heading hyperlinks to the Student index view
This code uses the information in the 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.
After you click the Last Name heading, students are displayed in descending last name order.
Additional resources
Добавление разбиения по страницам
Add column sort links
To add sorting to the Student Index page, you'll change the Index method of the Student controller and add code to the Student Index view.
Добавление гиперссылок заголовка столбца в представление индекса учащихся
Этот код использует сведения в ViewBag свойствах для настройки гиперссылок с соответствующими значениями строки запроса.
Чтобы проверить, работает ли сортировка, запустите страницу и щелкните заголовки столбцов Last Name и Date регистрации .
После того как вы щелкните заголовок Last Name (фамилия ), учащиеся будут отображаться в порядке убывания фамилий.
Next steps
In this tutorial, you:
- Add column sort links
- Add a Search box
- Add paging
- Create an About page
Advance to the next article to learn how to use connection resiliency and command interception.
В предыдущем уроке мы реализовали страницы для совершения CRUD-операций для сущностей Student. В этом уроке мы добавим сортировку, фильтрацию и разбиение по страницам, а также создадим страницу, на которой будет простая группировка.
На следующем изображении представлен окончательный вид страницы. Заголовки столбцов являются ссылками, реализующими сортировку по убыванию и возрастанию.
Добавление заголовков-сортировщиков в столбцы на странице Students Index
Для добавления сортировки вам нужно изменить метод Index контроллера Student и добавить код на представление Student Index.
Добавление сортировки в метод Index
В Controllers\StudentController.cs замените метод Index на следующий код:
При первом вызове страницы Index строки запроса нет, и студенты отображаются в порядке по возрастанию LastName, что указано как вариант по умолчанию в switch. После того, как пользователь щелкает на заголовке столбца, соответствующее значение sortOrder добавляется в строку запроса.
The two ViewBag variables are used so that the view can configure the column heading hyperlinks with the appropriate query string values:
Это тернарное утверждения. Первое утверждает, что, если sortOrder равен null или пустой, то значение ViewBag.NameSortParam устанавливается в “Name desc”, иначе устанавливается в пустую строку.
- Если сортируется по возрастанию по LastName, ссылка LastName должна указывать на сортировку по убыванию по LastName и ссылка EnrollmentDate на сортировку по возрастанию по Date соответственно.
- Если сортируется по убыванию по LastName, ссылки должны указывать на сортировку по возрастанию как по LastName так и по Date.
- Если сортируется по возрастанию по Date, ссылки должны указывать на сортировку по возрастанию по LastName и по убыванию по Date.
- Если сортируется по убыванию по Date, ссылки должны указывать на сортировку по возрастанию по LastName и по возрастанию по Date.
Добавление заголовков-ссылок в Student Index
В этом коде используется информация в свойствах ViewBag для заполнения ссылок подходящими значениями запроса. Запустите проект и щёлкните на заголовках, чтобы убедиться, что сортировка работает.
Добавление поиска
Чтобы добавить фильтрацию, вы должны добавить на представление текстовое поле и кнопку отправки и сделать соответствующие изменения в коде метода Index.
Изменение кода метода Index
В Controllers\StudentController.cs замените код метода Index
Мы добавили в метод Index параметр searchString, кляузу в LINQ-утверждение, с помощью которого выбираются только те студенты, имя или фамилия которых содержит строку поиска. Строка поиска получается из текстового поля, которое вы позже добавите на представление. Код, который добавляет кляузу where в запрос, выполняется только в том случае, если задано значение для поиска:
Добавление поиска на представление
В Views\Student\Index.cshtmlпрямо перед открывающим тегом table добавьте заголовок, текстовое поле и кнопку Search:
Запустите проект, введите что-нибудь в строку поиска и нажмите на кнопку Search чтобы убедиться в работе фильтрации.
Добавление разбиения по страницам
Для этого необходимо сначала установить NuGet-пакет PagedList, затем сделать изменения в методе Index и добавить на представление ссылки на страницы.
Установка NuGet-пакета NuGet Package
NuGet-пакет PagedList устанавливает тип коллекции PagedList. Когда вы добавляете в коллекцию этого типа результаты запроса, вам предоставляется набор свойств и методов для обеспечения разбиения результатов по страницам.
В Visual Studio выберите проект. Затем нажмите в меню Tools пунктLibrary Package Manager и потом Add Library Package Reference.
В Add Library Package Reference нажмите на вкладку Online слева и введите в строку поиска "pagedlist". Как только появится пакет PagedList нажмите Install.
Добавление функциональности разбиения по страницам в метод Index
В Controllers\StudentController.cs добавьте using PagedList:
Замените код метода Index:
Добавлен параметр page, несущий информацию о параметре, по которому в данный момент производится сортировка, и параметр в сигнатуре метода:
public ViewResult Index(string sortOrder, string currentFilter, string searchString, int? page)
При первом вызове страницы (или если пользователь не нажал на одну из ссылок на страницы), переменная page равна null. После нажатия в эту переменную помещается номер страницы.
Свойство ViewBag передаёт в представление текущий параметр сортировки для её сохранения при переходе на другие страницы:
Второе свойство ViewBag передаёт в представление строку фильтрации для того, чтобы при переходе на другую страницу введёная строка поиска не терялась и сохранялись настройки фильтрации. Кроме этого, если строка поиска меняется в случае перехода на другую страницу результатов, номер страницы должен быть скинут в 1, поскольку новая фильтрация предоставляет новый набор данных.
В конце метода запрос конвертируется вместо List в PagedList, после чего его можно передавать в представление, поддерживающее разбиение результатов по страницам.
В метод ToPagedList передаётся значение индекса страницы, которое равно 0, в отличие от номера страницы, который равен 1. Поэтому код извлекает 1 из номера страницы, чтобы получить значения индекса страницы (два знака вопроса обозначают оператор, определяющий значение по умолчанию для типа nullable, таким образом, выражение (page ?? 1) возвращает значение page в том случае, если оно имеет значение, или 1, если page равен null. Другими словами, установите pageIndex в page — 1 если page не равен null, или установите его в 1-1 если он равен null)
Добавление ссылок на страницы на представление
В Views\Student\Index.cshtml замените исходный код на:
Утверждение @model показывает, что представление принимает на вход объект типа PagedList вместо объекта типа List.
Текстовая строка инициализируется текущей строкой поиска чтобы пользователь мог переходить со страницы на страницу не теряя строку поиска:
Find by name: Html.TextBox("SearchString", ViewBag.CurrentFilter as string)
Ссылки в заголовках столбцов используют строку запроса для передачи текущей строки поиска в контроллер, чтобы пользователь мог сортировать возвращённые механизмом фильтра результаты:
В «подвале» страницы находится запись, демонстрирующая номер страницы и ссылки навигации:
Page [current page number] of [total number of pages] >>
Если результатов нет, показывается надпись "Page 0 of 0".
Щелкните ссылки на страницы в различных режимах сортировки и введите какую-либо строку поиска, чтобы убедиться, что всё работает в связке.
Создание страницы со статистикой
- Создать класс с моделью представления для данных, которые мы будем передавать в представление
- Изменить код метода About в контроллере Home.
- Изменить код представления About.
Создание модели представления
Создайте папку ViewModels и в ней создайте файл EnrollmentDateGroup.cs со следующим содержанием:
Изменение контроллера Home
В HomeController.cs добавьте необходимые using:
Добавьте переменную с контекстом базы данных:
private SchoolContext db = new SchoolContext();
Замените код метода About на:
LINQ-утверждения группируют сущности студентов по дате записи, затем вычисляют количество сущностей в каждой группе и сохраняют результат в EnrollmentDateGroup.
Из-за того, что данные не сразу же загружаются, lazy loading и explicit loading имеют общее название deferredloading.
В целом, если у вас есть необходимость в данных для каждой сущности, метод eager loading предлагает наилучшую производиетльность потому, что один запрос обычно эффективнее нежели множество запросов для каждой сущности. Для примера, представьте, что на каждом факультете проводится десять курсов. Пример для eager loading будет сопровождаться одним join-запросом. Примеры для lazy loading и explicit loading будут сопровождаться одиннадцатью.
С другой стороны, если доступ к navigation properties сущностям осуществляется редко или используется малое количество сущностей, lazy loading может быть эффективнее — eager loading будет загружать больше данных чем нужно. Обычно explicit loading используется только тогда, когда выключен lazy loading. Допустим, есть ситуация, когда lazy loading может быть выключен в процессе сериализации, когда вы уверены, что все navigation properties вам не нужны. Если lazy loading включен, все navigation properties загрузятся автоматически, так как сериализация обращается ко всем свойствам.
- При объявлении navigation properties пропустите указание модификатора virtual.
- Для всех navigation properties укажите LazyLoadingEnabled как false.
Создание страницы CoursesIndex
Сущность Course имеет navigation property, содержащую в себе сущность Department – сущность факультета, которому принадлежит данный курс. Чтобы отобразить имя факультета, нужно обратиться к свойству Name соответствующей сущности.
Создайте контроллер типа Course:
В Controllers\CourseController.cs обратите внимание на метод Index:
Автоматический scaffolding определяет использование eager loading для Department navigation property с помощью метода Include.
В Views\Course\Index.cshtml замените код на:
Были внесены следующие изменения:
- Заголовок изменён на Courses.
- Строки выровнены по левому краю.
- Добавлен стобец под заголовком Number, отображающий значение свойства CourseID. (Первичные ключи обычно не включаются в страницу, так как не имеют смысла, но в данном случае значение осмысленное и его необходимо показать.
- Заголовок последнего столбца изменен на Department.
Выберите пункт Courses чтобы увидеть список с названиями факультетов.
Создание InstructorsIndexPageсо списком курсов и слушателей этих курсов
Вы создадите контроллер и представление для сущности Instructor для отображения страницы Instructors Index:
- Список преподавателей отображает соответствующие данные сущности OfficeAssignment. Сущности Instructor и OfficeAssignment связаны один-к-нулю-или-к-одному. Для сущности OfficeAssignment используется eager loading.
- Когда пользователь выбирает преподавателя, отображаются связанные сущности Course. Сущности Instructor и Course связаны многие-ко-многим. Вы будете использовать eager loading для сущностей Course и связанным с ними сущностей Department. В этом случае lazy loading будет более эффективно, потому что необходимо выгружать данные о курсах только для выбранного преподавателя. Однако в примере показано использование eager loading.
- Когдап ользователь выбирает курс, отображаются данные сущности Enrollments. Сущности Course и Enrollment связаны один-ко-многим. Вы добавите explicit loading для сущности Enrollment и связанным с ней сущностей Student. (При включенном lazy loading использование Explicit loading необязательно, но мы просто покажем как работает explicit loading.)
На странице Instructor Index отображается три различных таблицы. Для этого мы создадим модель представления, включающую в себя три свойства, каждое из которых содержит в себе данные для каждой из таблиц.
В папке ViewModels создайте InstructorIndexData.cs:
Стили для выделенных столбцов
Для выделенных столбцов необходим отдельный цвет фона. Для того, чтобы сделать это, добавьте следующий код в Content\Site.css:
Создание контроллера и представлений для Instructor
Создайте контроллер типа Instructor:
В Controllers\InstructorController.cs добавьте using для ViewModels:
Сгенерированный код в методе Index определяет использование eager loading только для OfficeAssignment navigation property:
Замените метод Index следующим кодом, который загружает дополнительные данные и кладёт их в модель представления:
Метод принимает опциональные строковые параметры: ID значений выбранных преподавателя и курса, и затем передаёт необходимые данные в представление. ID поступают от ссылок Select на странице.
Код начинается созданием экземпляра модели представления и передачи в него списка преподавателей:
Мы определяем eager loading для Instructor.OfficeAssignment и Instructor.Courses navigation property. Для связанных сущностей Course eager loading определяется для Course.Department navigation property с использованием метода Select в методе Include. Результаты сортируются по фамилии.
Если выбран преподаватель, то данный преподаватель извлекается из списка преподавателей в модели данных, после чего свойство Courses инициализируется сущностями Course из соответствующей преподавателю Courses navigation property.
Метод Where возвращает коллекцию, но в данном случае условие, переданное методу, указывает на то, чтобы возвратить только одну сущность Instructor. Метод Single конвертирует коллекцию в одну сущность Instructor, что позволяет обратиться к соответствующему данной сущности свойству Courses.
Метод Single используется на коллекции если известно, что коллекция будет состоять из одного элемента. Данный метод выбрасывает исключения, если коллекция пустая или состоит из более чем одного элемента. Однако и в данном случае будет выброшено исключение (из-за свойства Course с ссылкой null). При вызове Single вместо отдельного вызова Where можно передать само условие:
.Single(i => i.InstructorID == id.Value)
.Where(I => i.InstructorID == id.Value).Single()
Далее, если выбран курс, то этот курс извлекается из списка курсов в модели. Затем свойство модели Enrollments инициализируется сущностями Enrollments navigation property.
И, наконец, возвращение в модель:
Редактированиепредставления Instructor Index
В Views\Instructor\Index.cshtml замените код на:
- Заголовок страницы изменён на Instructors.
- Moved the row link columns to the left.
- Убран столбец FullName.
- Добавлен столбец Office, отображающий item.OfficeAssignment.Location в том случае, если item.OfficeAssignment не null. (Из-за того, что здесь связь один-к-нулю-или-одному, с сущностью может быть не связана ни одна сущность OfficeAssignment.)
- Добавлен код, динамически добавляющий в контейнер tr выбранного преподавателя. Таким образом мы задаём цвет фона, используя CSS-класс. (атрибут valign будет полезен в будущем, когда мы добавим многостроковый столбец в таблицу)
- Перед ссылками в каждой строке добавлен новый ActionLink Select, что позволяет передать ID выбранного преподавателя в метод Index.
в Views\Instructors\Index.cshtml после контейнера table добавьте код, отображающий список курсов выбранного преподавателя.
Код загружает свойство модели представления Courses для отображения списка курсов, и отображает ссылку Select, с помощью которой в метод Index передаётся ID выбранного курса.
Выберите преподавателя, и увидите таблицу с курсами данного преподавателя и факультеты, на которых ведутся курсы.
Note если выбранная строка не меняет цвет, обновите страницу, иногда это нужно для загрузки файла .css.
После кода, который вы добавили, добавьте код, отображающий список студентов, учащихся на выбранном курсе.
Код загружает свойство модели представления Enrollments для отображения списка учащихся на выбранном курсе студентов.
Выберите преподавателя и щёлкните на курсе, чтобы увидеть учащихся студентов и их оценки.
Добавление ExplicitLoading
В InstructorController.cs и обратите внимание на то, как метод Index загружает список учащихся на выбранном курсе:
Во время загрузки списка преподавателей вы определили eager loading для Courses navigation property и свойства каждого из курсов Department, после чего отправили коллекцию Courses в модель представления, и теперь загружаете Enrollments navigation property из одной из сущностей в этой коллекции. Из-за того, что вы не определили eager loading для Course.Enrollments navigation property, данные этого свйоства появляются на странице в результате lazy loading.
Если отключить lazy loading, свойство Enrollments будет равно null независимо от того, сколько учащихся учится на этом курсе. В этом случае, чтобы инициализировать свойство Enrollments, вы должны определить для него eager loading или explicit loading. Для определения explicit loading замените код метода Index на:
После загрузки выбранной сущности Course, новый код явно загружает свойства Enrollments:
Затем явно загружаются сущности Student:
Обратите вниамние на то, что вы используете метод Collection для инициализации свойства коллекции, но для свойства с одним элементом вы используете метод Reference. Теперь можно открыть страницу Instructor Index – ничего не изменилось внешне, но изменился принцип загрузки данных.
Итак, вы использовали все три метода загрузки данных в navigation properties. В следующем уроке вы научитесь обновлять связанные данные.
Читайте также: