VB .NET - Introdução ao Acesso a dados com o Entity Framework para Novatos - II
Hoje eu vamos continuar o acesso a dados com EF. |
Na primeira parte deste artigo criamos o banco de dados e o Entity Data Model(EDM) que gerou o modelo de entidades que usaremos em nossa aplicação ASP .NET a ser criada neste artigo.
Criando o projeto ASP .NET e usando o Entity Data Model
Vamos criar uma aplicação ASP NET e mostrar como podemos realizar as operações CRUD para incluir, atualizar e deletar informações do banco de dados usando o modelo de entidades criado pelo Entity Framework.
Na verdade nosso projeto já foi criado na primeira parte do artigo, vamos agora implementar as funcionalidades CRUD aproveitando a estrutura já criada.
Vamos iniciar alterando o nome da página Contact.aspx criada por padrão para Clientes.aspx;
A seguir vamos abrir a master page Site.master e alterar o código conforme mostrado abaixo:
.... <div class="float-right"> <nav> <ul id="menu"> <li><a runat="server" href="~/">Home</a></li> <li><a runat="server" href="~/About.aspx">Sobre</a></li> <li><a runat="server" href="~/Clientes.aspx">Cadastro</a></li> </ul> </nav> </div> .... |
Vamos alterar também o conteúdo da página About.aspx.
Exibindo os clientes cadastrados
Ao iniciar a nossa aplicação ASP .NET a página Default.aspx deverá ser apresentada e vamos usá-la para exibir os clientes cadastrados.
Para isso vamos usar um controle Repeater e acessar os dados usando o Entity Data Model.
Altere o código da página Default.aspx conforme abaixo:
<%@ Page Title="Home Page" Language="VB" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.vb" Inherits="EF_AcessoDados._Default" %> <asp:Content runat="server" ID="FeaturedContent" ContentPlaceHolderID="FeaturedContent"> </asp:Content> <asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent"> <h2> Atualizar Clientes</h2> <br /> Exemplo de acesso aos dados dos Clientes <table border="1"> <tr> <td><strong>Cliente - ID</strong></td> <td><strong>Nome</strong></td> <td><strong>Endereco</strong></td> <td> <strong>Telefone</strong> </td> <td> <strong>Email</strong> </td> <td> </td> </tr> <asp:Repeater ID="rptClientes" runat="server"> <ItemTemplate> <tr> <td><%#DataBinder.Eval(Container.DataItem, "id") %> </td> <td> <%#DataBinder.Eval(Container.DataItem, "nome")%> </td> <td> <%#DataBinder.Eval(Container.DataItem, "endereco")%> </td> <td> <%#DataBinder.Eval(Container.DataItem, "telefone")%> </td> <td> <%#DataBinder.Eval(Container.DataItem, "email")%> </td> <td> <asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%#DataBinder.Eval(Container, "DataItem.id", "AtualizaCliente.aspx?id={0}")%>'>Atualizar</asp:HyperLink> </td> </tr> </ItemTemplate> </asp:Repeater> </table> </asp:Content> |
Abaixo temos o leiaute da página Default.aspx:
Agora abra o arquivo code-behind Default.aspx.vb e inclua o código a seguir:
Public Class _Default Inherits Page Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load Dim contexto As New CadastroEntities() rptClientes.DataSource = contexto.Clientes.ToList() rptClientes.DataBind() End Sub End Class |
O código acima é tudo que precisamos para acessar todos os clientes cadastrados.
Como assim ?
Mas onde esta conexão com o banco de dados ? E os objetos ADO .NET ? Onde esta o Command ? Onde esta o SQL ?
Observe a primeira linha : Dim contexto As New CadastroEntities()
Nela eu estou criando uma instância da classe CadastroEntities() que é o nosso contexto.
Esta classe encapsula a conexão com o banco de dados e os métodos de acesso e persistência.
Na segunda linha de código estou obtendo todos os clientes cadastrados e atribuindo ao controle Repeater: rptClientes.DataSource =
Observe a instrução: contexto.Clientes.ToList()
Ela retorna uma lista de clientes do tipo IEnumerable(Of Cliente) que são exibidos na página.
Dessa forma ao iniciarmos a aplicação iremos obter a exibição dos clientes no controle Repeater e do hyperlink -Atualizar - que quando clicando chama a página AtualizaCliente.aspx e passa o ID do cliente selecionado:
Vamos incluir então a página AtualizarCliente.aspx no projeto clicando na opção Add New Item do menu Project;
A seguir selecione o template Web Form using master page , informe o nome AtualizarCliente.aspx e clique em Add;
Selecione a master page Site.master e clique em OK;
Em seguida digite o código a seguir nesta página :
<%@ Page Title="" Language="vb" AutoEventWireup="false" MasterPageFile="~/Site.Master" CodeBehind="AtualizaCliente.aspx.vb" Inherits="EF_AcessoDados.AtualizaCliente" %> <asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server"> </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="FeaturedContent" runat="server"> </asp:Content> <asp:Content ID="Content3" ContentPlaceHolderID="MainContent" runat="server"> <h2> Atualiza Clientes</h2><br /> ID: <asp:Label ID="lblID" runat="server" Font-Bold="True" Text="Label"></asp:Label> <br /> Nome: <asp:Label ID="lblNome" runat="server" Font-Bold="True" Text="Label"></asp:Label> <br /> Endereco:<asp:Label ID="lblEndereco" runat="server" Font-Bold="True" Text="Label"></asp:Label> <br /> Telefone:<asp:TextBox ID="txtTelefone" runat="server"></asp:TextBox> <br /> Email:<asp:TextBox ID="txtEmail" runat="server" Width="295px"></asp:TextBox> <br /> <asp:Button ID="btnAtualiza" runat="server" onclick="btnAtualizar_Click" Text="Atualiza" /> <asp:Button ID="btnCancela" runat="server" onclick="btnCancelar_Click" Text="Cancela" /> <asp:Label ID="lblmsg" runat="server" style="font-weight: 700"></asp:Label> <br /> <asp:CheckBox ID="chkDeleta" runat="server" Text="Deletar este Cliente" /> <asp:Button ID="btnDeleta" runat="server" onclick="btnDeleta_Click" Text="Deletar" /> <br /> </asp:Content> |
O leiaute exibido pela página deverá ser o seguinte:
Vamos definir o código no arquivo code-behind AtualizarCliente.aspx.vb para cada evento Click de cada um dos botões de comando incluídos nesta página:
No evento Load da página digite o código a seguir:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load If IsPostBack = False Then If Request.QueryString("id") Is Nothing Then Response.Redirect("Default.aspx") End If Dim clienteID As Integer = Convert.ToInt32(Request.QueryString("id").ToString()) Dim contexto As New CadastroEntities() Dim cli As Cliente = contexto.Clientes.SingleOrDefault(Function(p) p.id = clienteID) lblID.Text = cli.id.ToString() lblNome.Text = cli.nome lblEndereco.Text = cli.endereco txtTelefone.Text = cli.telefone txtEmail.Text = cli.email Session("atualizaCliente") = cli End If End Sub |
Este código obtém o id do cliente via querystring e realiza uma consulta ao modelo de entidades obtendo o respectivo cliente exibindo suas informações na página AtualizarCliente.aspx.
Obs: Note a url gerada após clicar no cliente na página Default.aspx: localhost:60607/AtualizaCliente?id=1
1- O código do evento Click do botão Atualizar é exibido a seguir:
Protected Sub btnAtualizar_Click(sender As Object, e As EventArgs) Handles btnAtualiza.Click Dim clienteID As Integer = Convert.ToInt32(Request.QueryString("id").ToString()) Dim contexto As New CadastroEntities Dim cli As Cliente = db.Clientes.SingleOrDefault(Function(p) p.id = clienteID) cli.telefone = txtTelefone.Text cli.email = txtEmail.Text contexto.SaveChanges() lblmsg.Text = "Cliente atualizado com sucesso !!" End Sub |
Neste código estamos usando uma expressão lambda para obter um cliente a partir do seu id:
Dim cli As Cliente = db.Clientes.SingleOrDefault(Function(p) p.id = clienteID)
Note que o retorno é um objeto Cliente.
O
que são Expressões Lambda ? As expressões lambda foram incluídas no VS/VB 2008 para dar suporte a consultas LINQ. As cláusulas Where são assim compiladas como expressões lambdas e chamadas em itens aplicáveis do seu dataset. Podem ser consideradas uma forma de delegate que pode passar ou retornar outra função. Nota: Delegates permitem que uma classe use métodos de outra classe. Para saber mais sobre delegates leia o meu artigo: Usando Delegates No LINQ as expressões lambda são usadas para realizar ações sobre listas de objetos e com extensões de métodos. Uma expressão lambda é então uma função sem nome que calcula e retorna um valor único e podem ser usadas em qualquer lugar que um tipo delegate for válido. Exemplos : Function
(numero As Integer) numero + 1 => Expressão lambda que
aumenta o seu argumento e retorna um valor. |
O método SingleOrDefault usado retorna um único elemento, um elemento específico de uma sequência de valores, ou o valor padrão se o tal elemento não for encontrado; isto significa que se o mesmo for um tipo complexo você pode obter um valor null.
Após obter o objeto Cliente alteramos os valores para telefone e email (foi critério adotado mas que pode ser alterado) e usamos o método SaveChanges() para persistir as informações no banco de dados: contexto.SaveChanges()
3- O código do evento Click do botão Deletar é dado abaixo:
Protected Sub btnDeleta_Click(sender As Object, e As EventArgs) Handles btnDeleta.Click If chkDeleta.Checked = True Then 'deleta o contato Dim clienteID As Integer = Convert.ToInt32(Request.QueryString("id").ToString()) Dim contexto As New CadastroEntities() Dim cli As Cliente = contexto.Clientes.SingleOrDefault(Function(p) p.id = clienteID) contexto.Clientes.Remove(cli) contexto.SaveChanges() Response.Redirect("Default.aspx") End If Return End Sub |
Aqui novamente usamos a expressão lambda e após obter o objeto Cliente usamos o método Remove() para excluir o objeto do contexto: contexto.Clientes.Remove(cli)
Novamente usamos o método SaveChanges() para persistir as informações no banco de dados: contexto.SaveChanges()
3- O código do evento Click do botão Cancelar é dado abaixo:
Protected Sub btnCancelar_Click(sender As Object, e As EventArgs) Handles btnCancela.Click Response.Redirect("default.aspx") End Sub |
Incluindo um novo Cliente
Para incluir um novo cliente usamos a página Clientes.aspx a qual deverá ter o seguinte código:
<%@ Page Title="Contact" Language="VB" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Clientes.aspx.vb" Inherits="EF_AcessoDados.Contact" %> <asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent"> <h1>Adicionar Clientes<span class="auto-style5"><br /> </span> <table class="auto-style1"> <tr> <td class="auto-style2" colspan="2"> </td> </tr> <tr> <td class="auto-style3">Nome</td> <td class="auto-style3"> <asp:TextBox ID="txtNome" runat="server" Height="25px" Width="376px" CssClass="auto-style2"></asp:TextBox> </td> </tr> <tr> <td class="auto-style3">Endereço</td> <td class="auto-style3"> <asp:TextBox ID="txtEndereco" runat="server" Height="26px" Width="376px" CssClass="auto-style2"></asp:TextBox> </td> </tr> <tr> <td class="auto-style3">Telefone</td> <td class="auto-style3"> <asp:TextBox ID="txtTelefone" runat="server" Height="26px" Width="376px" CssClass="auto-style2"></asp:TextBox> </td> </tr> <tr> <td class="auto-style3">Email</td> <td class="auto-style3"> <asp:TextBox ID="txtEmail" runat="server" Height="24px" Width="376px" CssClass="auto-style2"></asp:TextBox> </td> </tr> <tr> <td class="auto-style2" colspan="2"> </td> </tr> <tr> <td class="auto-style2"> </td> <td class="auto-style3"> <asp:Button ID="btnAdicionar" runat="server" BackColor="#3399FF" Text="Adicionar" CssClass="auto-style4" /> <asp:Button ID="btnCancelar" runat="server" BackColor="#3399FF" Text="Cancelar" CssClass="auto-style4" /> </td> </tr> <tr> <td class="auto-style2" colspan="2"> <asp:Label ID="lblmsg" runat="server" style="color: #FF0000"></asp:Label> </td> </tr> </table> <br /> </h1> </asp:Content> <asp:Content ID="Content1" runat="server" contentplaceholderid="HeadContent"> <style type="text/css"> .auto-style2 { font-size: small; } .auto-style3 { color: #0033CC; font-size: small; } .auto-style4 { font-weight: bold; } </style> </asp:Content> |
O leiaute desta página deverá ficar assim:
Vamos agora definir o código no arquivo code-behind Clientes.aspx.vb conforme abaixo:
Public Class Contact Inherits Page Protected Sub btnAdicionar_Click(sender As Object, e As EventArgs) Handles btnAdicionar.Click If Not (String.IsNullOrWhiteSpace(txtNome.Text)) Or Not _ (String.IsNullOrWhiteSpace(txtEndereco.Text)) Or Not _ (String.IsNullOrWhiteSpace(txtTelefone.Text)) Or Not _ (String.IsNullOrWhiteSpace(txtEmail.Text)) Then 'cria um novo objeto cliente Dim cli As New Cliente 'atualiza os dados do objeto cli.nome = txtNome.Text cli.endereco = txtEndereco.Text cli.telefone = txtTelefone.Text cli.email = txtEmail.Text 'cria um novo contexto Dim contexto As New CadastroEntities 'adiciona a entidade ao contexto contexto.Clientes.Add(cli) 'persiste as informação no banco de dados contexto.SaveChanges() Else lblmsg.Text = "Informe os dados para incluir um novo Cliente" End If End Sub Protected Sub btnCancelar_Click(sender As Object, e As EventArgs) Handles btnCancelar.Click Response.Redirect("~/Default.aspx") End Sub End Class |
O código verifica se o usuário informou os valores no formulário e cria um novo objeto Cliente atualizando seus dados com esses valores.
A seguir criamos uma instância do contexto e incluímos o objeto cliente recém criado no contexto usando o método Add() para a seguir invocar o método SaveChanges() e assim persistir as informações no banco de dados.
Concluímos assim a implementação das operações CRUD usando o Entity Framework.
Observe que a ideia básica, pelo menos para este cenário bem simples no qual estou trabalhando, é basicamente a seguinte:
Se você estava acostumado ou já tinha visto a mesma implementação usando ADO .NET notou que a quantidade de código diminuiu e que não foi necessário usar instruções SQL ou instanciar objetos ADO .NET. Tudo isso é feito de forma transparente pelo Entity Framework em segundo plano.
Você deve então considerar o Entity Framework como uma alternativa viável para implementação de funcionalidades de acesso a dados em aplicações VB .NET.
Pegue o projeto completo aqui: EF_AcessoDados.zip
1Ts 4:3
Porque esta é a vontade de Deus, a saber, a vossa santificação: que vos abstenhais da prostituição,1Ts 4:4
que cada um de vós saiba possuir o seu vaso em santidade e honra,1Ts 4:5
não na paixão da concupiscência, como os gentios que não conhecem a Deus;1Ts 4:6
ninguém iluda ou defraude nisso a seu irmão, porque o Senhor é vingador de todas estas coisas, como também antes vo-lo dissemos e testificamos.1Ts 4:7
Porque Deus não nos chamou para a imundícia, mas para a santificação.Referências: