Neste artigo, vou continuar a criação de uma aplicação ASP .NET Core MVC usando o Entity Framework Core no Visual Studio 2017.
Vamos adicionar funcionalidades de classificação, filtragem e paginação à página Index de Estudantes e também criar uma página para realizar agrupamentos simples.
No artigo anterior, implementamos um conjunto de páginas web para realizar o CRUD para as entidades Estudante.
Estamos criando uma aplicação Web usando ASP.NET Core 1.1 MVC com Entity Framework Core 1.1 e Visual Studio 2017.
Adicionar links de classificação nas colunas da página Index
Para adicionar a classificação à página Index dos estudantes, vamos alterar o método Index do controlador EstudantesController e adicionar código à respectiva view Index.
Abra o arquivo EstudantesController.cs, altere o método Index e inclua o código destacado em azul mostrado abaixo:
// GET: Estudantes public async Task<IActionResult> Index(string ordem) { ViewData["NomeParm"] = String.IsNullOrEmpty(ordem) ? "nome_desc" : ""; ViewData["DataParm"] = ordem == "Data" ? "data_desc" : "Data"; var estudantes = from est in _context.Estudantes select est; switch (ordem) { case "nome_desc": estudantes = estudantes.OrderByDescending(est => est.SobreNome); break; case "Data": estudantes = estudantes.OrderBy(est => est.DataMatricula); break; case "data_desc": estudantes = estudantes.OrderByDescending(est => est.DataMatricula); break; default: estudantes = estudantes.OrderBy(est => est.SobreNome); break; } //return View(await _context.Estudantes.ToListAsync()); return View(await estudantes.AsNoTracking().ToListAsync()); }
Esse código recebe um parâmetro ordem da query string (string de consulta) na URL.
O valor da string de consulta é fornecida pela ASP.NET .Core MVC como um parâmetro para o método Action. O parâmetro será uma string que pode ser “Nome” ou “Data”, opcionalmente seguido por um sublinhado e a seqüência de caracteres “desc” para especificar a ordem decrescente. A ordem de classificação padrão é ascendente.
A primeira vez que a página Index é chamada, não há nenhuma string de consulta. Os estudantes são exibidos em ordem crescente por sobrenome, que é o padrão conforme estabelecido pela instrução switch. Quando o usuário clica em uma link de cabeçalho de coluna, o valor ordem apropriado é fornecido na string de consulta.
Os dois elementos ViewData (NomeParm e DataParm) são usados pela view para configurar os hiperlinks de cabeçalho de coluna com os valores apropriados de string de consulta.
ViewData["NomeParm"] = String.IsNullOrEmpty(ordem) ? "nome_desc" : ""; ViewData["DataParm"] = ordem == "Data" ? "data_desc" : "Data";
O código usa declarações ternárias e funciona assim:
- Na primeira instrução, o primeiro termo especifica que se o parâmetro ordem for nulo ou vazio, o parâmetro NomeParm deve ser definido como ‘nome_desc’. Caso contrário, ele deve ser definido como uma string vazia
- Na segunda instrução, o primeiro termo define que se o parâmetro ordem for igual a ‘Data’, o parâmetro DataParm será definido como igual a ‘data_desc’. Caso contrário, ele será igual a ‘Data’
Essas duas instruções permitem que a view exiba os hiperlinks de cabeçalho da coluna da seguinte forma:
Ordem de Classificação Atual | Hyperlink | Hyperlink Data |
Sobrenome ascending | descending | ascending |
Data ascending | ascending | ascending |
Data ascending | ascending | descending |
Data descending | ascending | ascending |
O método usa o LINQ to Entities para especificar a coluna a classificar. O código cria uma variável IQueryable antes da instrução switch, a modifica na instrução switch e chama o método ToListAsync após a instrução switch.
Quando você cria e modifica variáveis IQueryable, nenhuma consulta é enviada para o banco de dados. A consulta não é executada até converter o objeto IQueryable em uma coleção chamando um método como ToListAsync. Portanto, esse código resulta em uma consulta única que não é executada até a instrução View de retorno.
Nota: O primeiro ponto importante a destacar, é que a interface IQueryable herda de IEnumerable , de forma que tudo que o IEnumerable pode fazer, IQueryable também pode. A interface IQueryable é útil quando você está consultando uma coleção que foi carregada usando LINQ ou Entity Framework e você quer aplicar um filtro nesta coleção. (Leia o artigo: NET – Comparando IEnumerable com IQueryable – Macoratti).
Agora vamos alterar o código da view Index.cshtml conforme mostrado a seguir, incluindo as linhas destacadas em azul. (O código anterior foi comentado).
@model IEnumerable<UniversidadeMacoratti.Models.Estudante> @{ ViewData["Title"] = "Index"; } <h2>Estudantes</h2> <p> <a asp-action="Create">Criar Novo Estudante</a> </p> <table class="table"> <thead> <tr> <th> @*@Html.DisplayNameFor(model => model.SobreNome)*@ <a asp-action="Index" asp-route-ordem="@ViewData["NomeParm"]">@Html.DisplayNameFor(model => model.SobreNome)</a> </th> <th> @Html.DisplayNameFor(model => model.Nome) </th> <th> @*@Html.DisplayNameFor(model => model.DataMatricula)*@ <a asp-action="Index" asp-route-ordem="@ViewData["DataParm"]">@Html.DisplayNameFor(model => model.DataMatricula)</a> </th> <th></th> </tr> </thead> <tbody> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.SobreNome) </td> <td> @Html.DisplayFor(modelItem => item.Nome) </td> <td> @Html.DisplayFor(modelItem => item.DataMatricula) </td> <td> <a asp-action="Edit" asp-route-id="@item.EstudanteID">Editar</a> | <a asp-action="Details" asp-route-id="@item.EstudanteID">Detalhes</a> | <a asp-action="Delete" asp-route-id="@item.EstudanteID">Deletar</a> </td> </tr> } </tbody> </table>
Nota: Neste código, estamos usando as Tag Helpers: asp-action e asp-route-ordem e usamos a informação na propriedade ViewData para definir os hiperlinks com os valores apropriadas da string de consulta.
Execute o projeto e clique no link Sobrenome, e depois no link Data de Matricula para verificar a classificação em ação.
O resultado obtido pode ser visto na figura abaixo:
Na próxima parte do artigo vamos incluir uma caixa de Pesquisa (Search Box) na página Index.