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:&nbsp;&nbsp;
                  <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 />
                  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                  <asp:Button ID="btnAtualiza" runat="server" onclick="btnAtualizar_Click" Text="Atualiza" />
                  &nbsp;
                  <asp:Button ID="btnCancela" runat="server" onclick="btnCancelar_Click" Text="Cancela" />
                  &nbsp;&nbsp;&nbsp;
                  <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.
Function(n) n Mod 2 = 0 => Expressão lambda que verifica se um número é par.
Function(x) x ^ 3 => Expressão lambda que calcula o cubo de um número.

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">&nbsp;</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">&nbsp;</td>
                </tr>
                <tr>
                    <td class="auto-style2">&nbsp;</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:


José Carlos Macoratti