Este é o quarto artigo da série “ASP.NET MVC – Início, Meio e Fim” e, até chegarmos aqui muitos conceitos relacionados a este modelo de desenvolvimento e a framework ASP.NET foram abordados. Antes de prosseguirmos com o conteúdo do artigo de hoje, recapitulemos alguns destes:
- O que é ASP.NET MVC: no primeiro artigo da série vimos de forma detalhada o que é o ASP.NET MVC e entendemos que este se trata de uma framework disponibilizada pela Microsoft para construção de aplicações web sob o padrão MVC de desenvolvimento.
- URL Routing: ainda no primeiro artigo, apresentamos o mecanismo de rotas e entendemos como são efetuadas as chamadas e a interação entre as camadas de uma aplicação MVC.
- Estrutura hierárquica: já no segundo artigo da série, ao criarmos nossa primeira aplicação ASP.NET MVC, entendemos como se dá de forma prática a construção de uma aplicação MVC. Conhecemos as pastas “Models“, “Views” e “Controllers” e entendemos quais os tipos arquivos hospedados por cada uma delas.
- Models, Views, Controllers e Actions: evoluindo nos conceitos, no terceiro artigo criamos nosso primeiro controller, nossa primeira action e nossa primeira view.
Estes são os principais conceitos apresentados nos três primeiros artigos da série. Evidentemente que detalhes (e são muitos) são contemplados nos artigos. Além disso, ao final de cada artigo da série são disponibilizados vídeos sobre cada assunto, portanto, caso não tenha lido os três primeiros artigos e não possua os conhecimentos equivalentes, recomendo fortemente a leitura de ambos. Os links seguem:
- ASP.NET MVC – Início, Meio e Fim – Parte 1 – O que é ASP.NET MVC e para que serve?
- ASP.NET MVC – Início, Meio e Fim – Parte 2 – Criando e entendendo a estrtura de uma aplicação
- ASP.NET MVC – Início, Meio e Fim – Parte 3 – Criando e entendendo Controllers, Actions e Views
Acessando dados com ASP.NET MVC
No artigo anterior, criamos nosso primeiro controller onde, através da view “Index()“, criávamos um dicionário de dados (e o preenchiamos de forma manual) e exibiamos as informações deste dicionário na view correspondente. Em aplicações ASP.NET MVC é perfeitamente possível criarmos classes e métodos de acesso a dados de forma desacoplada, assim, ao invés de adicionarmos elementos aos nossos dicionários de forma manual, seria perfeitamente possível executar esta tarefa de forma automática, buscando estas informações de alguma fonte de dados. No artigo de hoje, realizaremos as operações básicas (inserir, editar, listar e remover registro) com dados em nossa aplicação ASP.NET MVC.
Um resumo sobre o Entity Framework 4 (EF4)
O Entity Framework é um ORM (Object-Relational Mapping) produzido pela Microsoft para agilizar o processo de acesso e manipulação dos dados das aplicações. Um ORM realiza o mapeamento da estrutura do banco de dados relacional e cria, com base neste, o modelo conceitual (classes, métodos e atributos e objetos). Assim, o desenvolvedor não precisa se preocupar com detalhes sobre os dados (forma como o acesso e a manipulação dos dados será realizada). Ele precisa preocupar-se apenas em utilizar corretamente os recursos do ORM. A Figura 1 apresenta uma visão geral sobre o EF4.
Figura 1: Estrutura interna do Entity Framework
Muito embora o Entity Framework traga benefícios consideráveis no trabalho com aplicações ASP.NET MVC (estes benefícios vêem da integração nativa com a framework) ele não é a única ferramenta disponível para realizar acesso a dados com ASP.NET MVC. Um bom exemplo a ser citado é o NHibernate. Você pode visualizar um bom artigo sobre a utilização do ASP.NET MVC com NHibernate no site do desenvolvedor Leandro Prado ou clicando diretamente aqui.
Para a construção da aplicação exemplo de nosso artigo, utilizaremos o Entity Framework. Futuramente escreverei um artigo especificamente sobre o EF4 e aí sim, abordaremos todas as características importantes da ferramenta.
Criando o banco de dados de exemplo da aplicação
Para que possamos realizar as operações com dados, evidentemente precisamos estar com o banco de dados disponível. Portanto, vamos a criação dele. Não darei muitos detalhes sobre o processo de criação do banco e das tabelas, pois este, não é o escopo deste artigo. A Figura 2 apresenta o DER (Diagrama Entidade Relacionamento) de nossa base de dados.
Figura 2: DER da aplicação exemplo
Em seguida, implementamos o modelo apresentado pela Figura 2 no SQL Server, como pode ser visualizado na Figura 3.
Figura 3: Banco criado através do SQL Server Management Studio
O que faremos a seguir é implementar as operações básicas de CRUD para nossa aplicação, isto é, para usuários, criaremos rotinas de inserção, edição, remoção e listagem. Mãos a obra?
Criando o modelo de dados
Com o projet0 “SitePessoalMVC” aberto, o que faremos primeiro é criar um contexto de dados para nossa aplicação, ou seja, iremos conectar nossa aplicação a base de dados criada anteriormente utilizando o Entity Framework 4. Conforme mencionado nos artigos anteriores, a camada do modelo MVC responsável pelos dados é “Model“, portanto, para criarmos o acesso aos dados, iremos adicionar um modelo de dados ao diretório “Model” de nossa aplicação.
Ao clicar com o botão direito do mouse sobre a pasta “Model” na Solution Explorer e selecionar a opção “Add new item…” uma janela de opções será exibida. A esquerda selecione a guia “Data” e, a direita, selecione a opção “ADO.NET Entity Data Model“. Nomeie este arquivo conforme a conveniência. Sugestivamente nomeamos como “ModeloSitePessoalMVC.edmx“. A Figura 4 ilustra este procedimento.
Figura 4: Criando o modelo de dados da aplicação
Ao clicar em “Add” uma nova janela será apresentada. Neste momento, configuraremos nosso modelo de dados, ou seja, informaremos ao Entity Framework tudo o que ele precisa saber para que o mapeamento seja realizado de forma correta. Nesta janela duas opções são apresentadas. A primeira “Generate from database” e a segunda “Empty model“. Na primeira opção o EF4 utilizará uma base já existente como referência para a modelagem. Na segunda opção, através do EF4 iremos criar um novo modelo conceitual (classes, atributos e métodos) e, através dele gerar o modelo físico relacional de dados. Como já possuímos nossa base de dados devidamente criada e configurada, a opção que nos interessa nesta tela é a primeira “Generate from database“, em seguida, pressione “Next“. A Figura 5 apresenta esta escolha.
Figura 5: Criando um modelo com base em base de dados pré-existente
A tela seguinte nos dá as opções de conexão com a base de dados. Neste momento, devemos escolher a qual base de dados o EF4 deve se conectar para criar o modelo conceitual de dados, se queremos que o EF4 respeite a regra de case-sensitive para a string de conexão e o nome que atribuiremos a esta conexão. Como nossa base de dados foi criada recentemente e ainda não nos conectamos a ela, o que faremos é clicar sobre o botão “New connection” a frente da lista suspensa, assim, estaremos criando uma nova conexão com o banco de dados. Na tela que se apresenta, você deve selecionar o servidor do banco de dados (sua máquina ou um servidor remoto) onde está localizada a fonte de dados, as informações de autenticação (Windows authentication ou SQL Server Authentication) e a base de dados a qual pretende se conectar e clicar em OK. A Figura 6 apresenta este procedimento.
Figura 6: Configurando a nova conexão com a fonte de dados
Se tudo ocorreu conforme o esperado, ao clicar em OK você deverá voltar a tela anterior. Note agora que, ao expandir a lista suspensa, um novo banco de dados apareceu entre os já existentes, no meu caso: “fabricio-pc.BDExemplosMVC.dbo”. Selecione esta nova base de dados, marque a opção “Yes, include the sensitive data in the connection string.” e nomeie a string de conexão como “StringConexaoExemplosMVC”. A Figura 7 apresenta esta tela com a configuração final.
Figura 7: Configurações da conexão
Clicando em “Next” uma nova janela será apresentada. Nesta janela é possível escolher quais aspectos de sua base de dados você deseja que o EF4 faça o mapeamento. Em nosso caso, queremos apenas as tabelas, mas é perfeitamente possível “trazer” views, stored procedures, etc. Mais abaixo, temos a opção de nomear nosso modelo. Sugestivamente nomearemos como “ModeloDados” e clicaremos em “Finish“. O resultado desta configuração pode ser visualizado na Figura 8.
Figura 8: Modelo conceitual de dados gerado a partir do modelo físico
Se você não conhecia o poder do Entity Framework 4 agora já conhece. O que fizemos aqui foi, com base em um banco de dados físico (tabelas, colunas e relacionamentos), criar um modelo de dados lógico (classes, métodos e atributos), assim, todas as manipulações de dados são realizadas a nível de classes e métodos, ficando a cargo do ORM a forma como estas manipulações se darão no banco de dados. Note que todas as características do banco de dados foram mantidas no modelo conceitual: relacionamento, chaves primárias, tipos de dados, etc.
Inserindo novos usuários
Com nosso modelo de dados já pronto, podemos então codificar nossas actions para que elas insiram, editem, removam e listem usuários. A primeira destas tarefas consiste na inserção de novos usuários, assim, dê um duplo clique sobre o controller “UsuariosController” (criado no terceiro artigo desta série). Procure a action “Create“. Note que existem duas actions “Create“. Uma delas possui o atributo “[HttpPost]“. Basicamente, a action que possui o o atributo em seu cabeçalho é aquela invocada no moment0 em que solicitamos o postback com os dados fornecidos pelo usuário no formulário de cadastro. A action que não possui este atributo, é aquela invocada por default pela framework MVC através do URL routing: http://seu-endereco/Usuarios/Create. Primeiramente iremos criar o formulário para o cadastro dos dados de usuário, portanto, vá até a action “Create” (sem HttpPost) e em seu interior adicione o código apresentado pela Listagem 1.
[csharp]
public ActionResult Create()
{
return View(new tbUsuarios());
}
[/csharp]
Listagem 1: Retornando os dados da classe “tbUsuarios” para view
Como é possível notar, o código apresentado pela action “Create” é extramente simples. A única responsabilidade desta action é retornar os dados constantes da classe “tbUsuarios”, assim, quando criarmos nossa view fortemente tipada, a framework saberá como realizar o binding das informações. Agora que já possuímos a codificação de nossa action, podemos criar nossa view que conterá o formulário. Para isso, clique com o botão direito do mouse sobre sobre o nome da action (neste caso Create) e selecione a opção “Add view…“. Na janela que se abre, você pode parametrizar views. Alguns parâmetros possíveis de serem personalizados:
- Fortemente ou fracamente acoplada: É possível “amarrar” a construção da view ao modelo de dados. Para isso, basta ticar a opção “Create a strongly-typed view“. No caso da associação, dizemos que a view é fortemente tipada, caso contrário, dizemos que a view é fracamente acoplada.
- View Content: É possível utilizar templates em associação com helpers para construir views. As operações básicas de CRUD possuem modelos prontos que são disponibilizados pela framework. Ao selecionar um formato de “view content” o que estará fazendo na realidade é escolhendo um template para construção da view.
- Master Page: É possível criar views que herder padrões visuais através de Master Pages. Para isso, basta selecionar a opção “Select master page” e indicar o caminho físico da mesma.
- Partial View: É possível ainda criar views parciais, ou seja, views com as extensões .ascx (semelhantes aos web user controls) do ASP.NET Web Forms. Estas carregam conteúdos específicos em regiões diferentes de uma mesma view.
A Figura 9 apresenta a configuração final da view “Create“. Uma observação importante a ser realizada aqui é que, views não necessariamente precisam possuir o mesmo nome das action’s. Muito embora seja uma prática recomendável, isto não é uma regra.
Figura 9: Configuração da view “Create“
Conforme ilustra a Figura 9, nossa view será fortemente tipada e, neste caso, está “amarrada” a classe “tbUsuarios”, utilizará o template de create, herdará o padrão visual da master page localizada e “~/Views/Shared/Site.Master” e será “renderizada” em “MainContent“. Ao clicar em “Add” uma nova view chamada “Create.aspx” será criada, conforme pode ser constatado em “~/Views/Usuarios”. A Listagem 2 apresenta o código da view a qual nos referimos:
[html]
<%@ Page Title=”” Language=”C#” MasterPageFile=”~/Views/Shared/Site.Master” Inherits=”System.Web.Mvc.ViewPage<SitePessoalMVC.Models.tbUsuarios>” %>
<asp:Content ID=”Content1″ ContentPlaceHolderID=”TitleContent” runat=”server”>
Create
</asp:Content>
<asp:Content ID=”Content2″ ContentPlaceHolderID=”MainContent” runat=”server”>
<h2>Create</h2>
<% using (Html.BeginForm()) {%>
<%: Html.ValidationSummary(true) %>
<fieldset>
<legend>Fields</legend>
<div class=”editor-label”>
<%: Html.LabelFor(model => model.IDUsuario) %>
</div>
<div class=”editor-field”>
<%: Html.TextBoxFor(model => model.IDUsuario) %>
<%: Html.ValidationMessageFor(model => model.IDUsuario) %>
</div>
<div class=”editor-label”>
<%: Html.LabelFor(model => model.NomeCompleto) %>
</div>
<div class=”editor-field”>
<%: Html.TextBoxFor(model => model.NomeCompleto) %>
<%: Html.ValidationMessageFor(model => model.NomeCompleto) %>
</div>
<div class=”editor-label”>
<%: Html.LabelFor(model => model.Username) %>
</div>
<div class=”editor-field”>
<%: Html.TextBoxFor(model => model.Username) %>
<%: Html.ValidationMessageFor(model => model.Username) %>
</div>
<div class=”editor-label”>
<%: Html.LabelFor(model => model.Password) %>
</div>
<div class=”editor-field”>
<%: Html.TextBoxFor(model => model.Password) %>
<%: Html.ValidationMessageFor(model => model.Password) %>
</div>
<p>
<input type=”submit” value=”Create” />
</p>
</fieldset>
<% } %>
<div>
<%: Html.ActionLink(“Back to List”, “Index”) %>
</div>
</asp:Content>
[/html]
Listagem 2: Código da view “Create.aspx“
A Figura 10 apresenta a view em execução. O principal aspecto a ser ressaltado no código da Listagem 2 é a presença maciça do helper “Html”. Isso se deve ao fato de estarmos utilizando um template para create. Basicamente o que a framework criou com a ajuda do helper foi, para cada elemento do meu formulário um correspondente com bind automático (através de expressões lambda), assim, ao adicionar os dados no formulário, todas as informações já estão automaticamente “linkadas” com as propriedades da classe “tbUsuarios”.
Figura 10: View com formulário de cadastro de usuários em execução
Evidentemente que, como utilizamos um template para geração do formulário constante na view, os nomes dos campos, header’s e demais aspectos da mesma apresentam-se em inglês ou com a semântica não ideal. Todas as personalizações podem ser realizadas facilmente, já que o código gerado pela framework para view é limpo e semântico. No terceiro artigo desta série, apresentamos alguns procedimentos para realizar personalizações nas views.
Muito bem, o formulário está criado e pronto para receber os dados de cadastro, entretanto, ainda não implementamos código para o envio dos dados para o banco de dados, ou seja, ainda não implementamos o cadastro de usuário de fato. Para isso, localize a action “Create” cujo cabeçalho é decorado com o atributo “[HttpPost]” e, substitua o código da action pelo código apresentado pela Listagem 3.
[csharp]
[HttpPost]
public ActionResult Create(tbUsuarios objUsuario)
{
try
{
modelo.AddTotbUsuarios(objUsuario);
modelo.SaveChanges();
return RedirectToAction(“Index”);
}
catch
{
return View();
}
}
[/csharp]
Listagem 3: Realizando post com dados fornecidos
A action apresentada pela Listagem 3 será invocada no momento em que o botão “Create” com os dados do formulário for pressionado. VocÊ deve estar se perguntando: e os Request.QueryString() para cada campo do formulário? Mas, e a sentença SQL que faz o Insert no banco? Os aspectos da Listagem 3 responsáveis por esta mágica são apresentados a seguir:
- Linha 1: Conforme mencionado anteriormente, o atributo HttpPost informa a framework que a action deve ser invocada quando houver o postback.
- Linha 2: A action recebe como parâmetro um objeto de “tbUsuarios” (este objeto virá quando o postback for realizado) lembram-se do bind automático?
- Linha 6: Invocamos o método “AddTotbUsuarios” e passamos como parâmetro o objeto que chegou para a action, simplificando, o EF4 está adicionando cada uma das propriedades de “objUsuario” em cada coluna da tabela “tbUsuarios”. Como? Isso não é problema nosso :-).
- Linha 7: Atualizamos o modelo e aí sim, a gravação é realizada na base de dados.
É importante salientar que, “modelo” é uma instância da classe “StringConexaoExemploMVC”, ou seja, da classe de contexto que definimos quando criamos nosso modelo conceitual com o Entity Framework. Esta instanciação, neste caso, ocorre na primeira linha do controller “UsuariosController”, como pode ser visto abaixo.
[csharp]
StringConexaoExemploMVC modelo = new StringConexaoExemploMVC();
[/csharp]
Como é é uma classe que herda de “ObjectContext” ela implementa os métodos inerentes a cada uma das entidades do modelo conceitual.
A Figura 11 apresenta o sucesso da inserção de um novo usuário.
Figura 11: Cadastro de novo usuário realizado com sucesso
Você deve estar se perguntando: mas e a validação de formulários? Não tem como ser realizada? Acalme-se, tem como ser feita sim e de várias formas. O próximo artigo desta série trata especificamente de validação de campos de formulários. Enquanto não evoluímos para validação de formulários, prossigamos com o conteúdo deste artigo e vejamos como é possível listar usuários cadastrados.
Listando usuários cadastrados
Agora que já possuimos o mecanismo de cadastro de usuários, podemos criar um mecanismo de listagem de usuários. Listar elementos presentes no banco de dados são uma tarefa comumente solicitada nos sistemas de forma geral para as mais variadas tarefas, portanto, vejamos como listar dados no ASP.NET MVC de forma extremamente simplificada.
Ainda no controller “UsuariosController“, criaremos uma nova action – esta será chamada “List” e seu código pode ser visualizado na Listagem 4.
[csharp]
public ActionResult List()
{
var usuarios = from u in modelo.tbUsuarios
orderby u.NomeCompleto ascending
select u;
return View(usuarios.ToList());
}
[/csharp]
Listagem 4: Listando os usuários cadastrados
É notória a simplicidade do código apresentado pela Listagem 4. O que fazemos aqui é retornar todos os dados presentes em “tbUsuarios” com LINQ e armazenar no objeto “usuarios”. Em seguida, através do método “ToList()” retornamos uma lista de valores para a view. Clicando com o botão direito sobre o nome da action e selecionando “Add view…” obtemos o resultado apresentado na Figura 12. A única mudança em relação a geração da view “Create” está no tipo de template utilizado para geração da mesma. Como estamos listando registros, evidentmente que o template utilizado foi “List“.
Figura 12: Listando usuários cadastrados
Editando informações de usuários
Já criamos rotinas para adicionar novos usuários ao sistema e listar estes usuários. Falta-nos ainda editar informações de usuários já existentes e remover usuários. Vamos então a rotina de atualização de registros. A lógica deste procedimento é rigorosamente a mesma do procedimento de inserção de novos registros, ou seja, temos duas actions para realizar esta tarefa. Uma responsável por “gerar” o formulário com os dados a serem atualizados e a outra com a função de atualizar estes dados de forma efetiva, portanto, um é decorado com o atributo “[HttpPost]” no cabeçalho. Ainda no controller “UsuariosController” localize a action “Edit” e, em seu interior adicione o código apresnetado pela Listagem 5.
[csharp]
public ActionResult Edit(long id)
{
var usuarioSel = from us in modelo.tbUsuarios
where us.IDUsuario == id
select us;
return View(usuarioSel.Single());
}
[/csharp]
Listagem 5: Gerando formulário com dados do usuário selecionado
Sem muitas novidades aqui. Simplesmente o que realizamos foi uma busca com LINQ selecionando o registro pelo ID do usuário. Este ID é enviado pelo próprio helper “Html” em associação como template “List”m cujo resultado é visualizado na Figura 12. Utilizamos o método “Single” para retornar apenas o registro retornado pelo LINQ.
Agora, para atualizarmos de fato os dados do usuário selecionado, na action “Edit” específica para o postback, adicione o código apresentado na Listagem 6.
[csharp]
[HttpPost]
public ActionResult Edit(long id, FormCollection collection)
{
try
{
var usuarioSel = from us in modelo.tbUsuarios
where us.IDUsuario == id
select us;
UpdateModel(usuarioSel.SingleOrDefault());
modelo.SaveChanges();
return RedirectToAction(“Index”);
}
catch
{
return View();
}
}
[/csharp]
Listagem 6: Atualizando dados do usuário selecionado
Na Listagem 6, novamente o que fazemos é selecionar o usuário e passar seus dados (através de id e de FormCollection) para o método “UpdateModel()” para que a atualização seja realizada de fato na base de dados novamente pelo método “SaveChanges()” do modelo. O resultado final da edição dos dados do usuário pode ser visualizado na Figura 13.
Figura 13: Atualizando dados do usuário
Removendo registros da base de dados
Finalmente, após criarmos as rotinas de inserção, listagem e edição, para completarmos as quatro operações básicas propostas neste artigo, implementaremos a seguir a remoção de registros da base de dados. Novamente, a lógica é rigorosamente a mesma dos demais procedimentos, ou seja, uma action exibe os dados e outra, com o postback realizado remove o registro.
Localize a action “Delete” no controller “UsuariosController”. Na primeira action, aquela responsável pela exibição dos dados em primeira instância, adicione o código apresentado pela Listagem 7.
[csharp]
public ActionResult Delete(long id)
{
var usuarioDel = from ud in modelo.tbUsuarios
where ud.IDUsuario == id
select ud;
return View(usuarioDel.SingleOrDefault());
}
[/csharp]
Listagem 7: Selecionando o registro para remoção
Sim eu sei, parece que está tudo ficando repetitivo. Mas é que a simplicidade do processo é muito grande. Note, novamente, selecionamos o registro a ser removido (através de seu ID via LINQ) assim como fizemos para editar e retornamos os dados para view. Novamente, ao adicionar a view e selecionarmos o template “Delete” temos a exibição conforme apresenta a Figura 14.
Figura 14: Confirmando dados para remoção
Ao clicarmos em “Delete” a ação invocada será “Delete” cujo cabeçalho está decorado com “HttpPost“. O código da responsável por remover o registro da base de dados é simples e pode ser visualizado na Listagem 8.
[csharp]
[HttpPost]
public ActionResult Delete(long id, FormCollection collection)
{
try
{
var usuarioDel = from ud in modelo.tbUsuarios
where ud.IDUsuario == id
select ud;
modelo.DeleteObject(usuarioDel.SingleOrDefault());
modelo.SaveChanges();
return RedirectToAction(“Index”);
}
catch
{
return View();
}
}
[/csharp]
Listagem 8: Removendo o usuário da base de dados
A novidade no código apresentado pela Listagem 8 é o método “DeleteObject()” que ao receber os dados da coleção e o ID do usuário remove o registro primeiro do modelo e depois fisicamente do banco de dados, conforme pode ser visualizado na Figura 15.
Figura 15: Registro removido com sucesso
Conclusões
Este artigo tinha como objetivo principal apresentar a principal forma de acesso a dados com ASP.NET MVC, isto é, utilizando o Entity Framework. Muito embora esta deva ser atualmente a principal abordagem, não é a única. É possível obter os mesmos resultados utilizando outros ORM’s, como é o caso do NHibernate, por exemplo.
De qualquer forma, este artigo espera ter cumprido seu objetivo ao apresentar o básico e a facilidade para se produzir as operações básicas de sistema de pequeno porte. Evidentemente que o ASP.NET MVC é muito mais do que o que foi apresentado aqui. Este artigo pretende ser o startup para que, ao estudar e aprofundar seus conhecimentos, você possa construir aplicações robustas e funcionais.
Continue acompanhando esta série, pois, nosso estudo não acaba aqui. No próximo artigo falaremos um pouco sobre validação de formulários, via Data Annotations e via JQuery. Nos artigos futuros, ainda nos esperam: ASP.NET razor, testes com ASP.NET MVC, helpers, views parciais e muito mais.
Se você gostou ou não deste artigo, por favor, peço para que deixe seu comentário. Ele é a única forma de sabermos se o objetivo está sendo alcançado e como podemos melhorar os textos e metodologias de escrita para ensinar cada vez melhor.
Um grande abraço a todos e até o próximo! :-).
Pingback: ASP.NET MVC – Início, Meio e Fim – Parte 4 | .NET Interior
Pingback: ASP.NET MVC – Início, Meio e Fim – Parte 5 – Fabrício Sanchez