Neste artigo vou continuar a criação de uma aplicação ASP .NET Core MVC usando o Entity Framework Core no Visual Studio 2017.
Estamos criando uma aplicação Web usando ASP.NET Core 1.1 MVC com Entity Framework Core 1.1 e Visual Studio 2017.
No artigo anterior implementamos a classificação por colunas na página Index dos estudantes.
Neste artigo vamos continuar incrementando a página Index incluindo uma caixa de pesquisa na página para filtrar dados por nome e/ou sobrenome.
1 – Filtrando dados : Incluindo um filtro no controlador
Vamos agora adicionar um filtro na página Index dos estudantes. Para isso, vamos ter que adicionar uma caixa de texto e um botão de envio na view Index e realizar alterações correspondentes no método Action Index do controlador EstudantesController.
A caixa de texto permitirá que o usuário digite uma seqüência de caracteres para procurar nos campos nome e sobrenome.
Vamos começar implementando a funcionalidade para realizar um filtro de dados no método Index do controlador Estudantes.
Abra o arquivo EstudantesController.cs e altere o método Index conforme mostrado a seguir, incluindo as linhas destacadas em azul no código:
// GET: Estudantes public async Task<IActionResult> Index(string ordem, string filtro) { ViewData["NomeParm"] = String.IsNullOrEmpty(ordem) ? "nome_desc" : ""; ViewData["DataParm"] = ordem == "Data" ? "data_desc" : "Data"; ViewData["filtro"] = filtro; var estudantes = from est in _context.Estudantes select est; if (!String.IsNullOrEmpty(filtro)) { estudantes = estudantes.Where(s => s.SobreNome.Contains(filtro) || s.Nome.Contains(filtro)); } 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 estudantes.AsNoTracking().ToListAsync()); }
Neste código, incluímos um novo parâmetro chamado filtro do tipo string no método Index. O valor de filtro será uma cadeia de caracteres e será recebido de uma caixa de texto que iremos adicionar na view Index.
Além disso, incluímos na instrução LINQ uma cláusula Where que seleciona apenas os estudantes com nome e sobrenome que contém a string informada em filtro. Essa instrução somente será executada se houver um filtro informado.
Neste código, estamos usando a cláusula Where em um objeto IQueryable, e o filtro será processado no servidor. Em alguns cenários podemos usar o Where como um método de extensão em uma coleção na memória. Por exemplo, suponha que você altere a referência _context.Estudantes para que em vez de usar um DBSet do EF, ele faça referência a um método de um repositório que retorna uma coleção IEnumerable. O resultado seria normalmente o mesmo, mas em alguns casos pode ser diferente.
Por exemplo, a implementação do .NET Framework para o método Contains realiza uma comparação sensível à maiúsculas e minúsculas por predefinição, mas no SQL Server isto é determinado pela definição de collation da instância do SQL Server.
Essa configuração padrão é insensível a maiúsculas e minúsculas. Você pode chamar o método ToUpper para tornar o teste explicitamente insensível a maiúsculas e minúsculas assim: Where (est => est.Sobrenome.ToUpper().Contains(filtro.ToUpper()).
Isso garantiria que os resultados permaneçam os mesmos se você alterar o código mais tarde para usar um repositório que retorna uma coleção IEnumerable em vez de um objeto IQueryable (quando você chama o método Contains em uma coleção IEnumerable, você obtém a implementação do .NET Framework, e, quando você chama o método em um objeto IQueryable, você obtém a implementação do provedor do banco de dados).
No entanto, há uma penalidade de desempenho para esta solução. O código ToUpper colocaria uma função na cláusula WHERE da instrução SELECT TSQL. Isso impediria o otimizador de usar um índice. Dado que o SQL é principalmente instalado como insensível a maiúsculas e minúsculas, é melhor evitar o código ToUpper até migrar para um armazenamento de dados sensível a maiúsculas e minúsculas.
2 – Filtrando dados: Adicionando uma caixa de Pesquisa
Vamos agora adicionar uma caixa de pesquisa na view Index da pasta Views/Estudantes para que o usuário possa informar a cadeia de caracteres usada para filtrar os dados.
Abra o arquivo Index.cshtml e inclua o código destacado em azul abaixo, antes da tag Table para criar um título, uma caixa de texto e um botão Procurar:
@model IEnumerable<UniversidadeMacoratti.Models.Estudante> @{ ViewData["Title"] = "Index"; } <h2>Estudantes</h2> <p> <a asp-action="Create">Criar Novo Estudante</a> </p> <form asp-action="Index" method="get"> <div class="form-actions no-color"> <p> Procurar por nome : <input type="text" name="filtro" value="@ViewData["filtro"]" /> <input type="submit" value="Procurar" class="btn btn-default" /> | <a asp-action="Index">Retornar para lista</a> </p> </div> </form> <table class="table"> <thead> <tr> <th> <a asp-action="Index" asp-route-ordem="@ViewData["NomeParm"]">@Html.DisplayNameFor(model => model.SobreNome)</a> </th> <th> @Html.DisplayNameFor(model => model.Nome) </th> <th> <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: Novamente estamos usando as Tag Helpers <form> e asp-action.
Neste código usamos a informação na propriedade ViewData para definir os hiperlinks com os valores apropriadas da string de consulta.
Este código usa a tag helper <form> para adicionar a caixa de texto de pesquisa e o botão. Por padrão, a tag helper <form> envia dados de formulário com um POST, o que significa que os parâmetros são passados no corpo da mensagem HTTP, e não na URL como uma string de consulta.
Quando você especifica HTTP GET, os dados do formulário são passados na URL como strings de consulta, o que permite aos usuários marcar o URL. As diretrizes do W3C recomendam que você use GET quando a ação não resultar em uma atualização.
Execute o projeto, abra a página dos estudantes, e a seguir informe um nome para busca. O resultado obtido pode ser visto na figura abaixo:
Na próxima parte do artigo vamos incluir o recurso de paginação na página Index.