Entity Framework 4 - Manutenção de dados com GridView em Camadas - 2


Na primeira parte deste artigo iniciamos a construção da nossa aplicação no Visual Web Developer Express 2010 criando a solução e os projetos onde criamos a camada de acesso a dados definindo as interfaces, classes abstratas e classes concretas usando os recursos do Entity Framework.

Neste ponto nossa solução deverá possuir a seguinte estrutura, onde notamos no projeto DAL a interface, classe abstrata e o Entity Data Model representado pelo arquivo Macoratti.edmx

Vamos continuar definindo as camadas de negócio e a interface com o usuário usadas no projeto.

Criando a camada de negócio (BLL)

Antes de iniciar temos que definir uma referência ao projeto DAL que criamos pois a camada de negócio precisa enxergar a camada de acesso a dados para ter acesso às classe nela criadas.

Clique com o botão direito sobre o projeto BLL e selecine Add Reference;

A seguir na janela Add Reference selecione o projeto DAL e clique em OK;

Nossa camada de negócios irá conter apenas duas classes, uma relativa a categorias e outra a produtos. Como você ja deve saber é na camada de negócio que residem as regras do negócio e como nossa aplicação é muito simples nossas classes serão definidas sem nenhuma regra e por isso não conterão nenhum método.

Vamos começar criando a classe concreta relacionada às categorias.

Clique com o botão direito sobre o projeto BLL e selecione Add -> New Item;

A seguir selecione o template Class e informe o nome Categoria_BLL.vb e clique em Add;

A seguir defina o seguinte código no arquivo Categoria_BLL.vb:

Imports DAL.DAL
Namespace BLL
        Public Class Categoria_BLL
                      Inherits categoria_DAL

        End Class
End Namespace

Como eu disse a nossa classe Categoria_BLL não contém nenhum método mas herda da classe concreta categoria_DAL que herda da classe abstrata Abstract_Crud, dessa forma ao referenciar a classe da camada de negócio teremos acesso a todos os métodos definidos na class Abstract_Crud.

Vamos agora criar a classe relacionada aos produtos.

Clique com o botão direito sobre o projeto BLL e selecione Add -> New Item;

A seguir selecione o template Class e informe o nome Produto_BLL.vb e clique em Add;

A seguir defina o seguinte código no arquivo Produto_BLL.vb:

Imports DAL.DAL
Namespace BLL
        Public Class Produto_BLL
                      Inherits produto_DAL

        End Class
End Namespace

Da mesma forma temos uma classe anêmica contendo apenas a assinatura com a palavra inherits que indica que ela herda da classe produto_DAL que herda da classe abstrata Abstract_Crud.

E isso é todo que temos que fazer na camada de negócios.

Criando a camada de interface (IU)

A nossa camada de interface será uma aplicação web e nela iremos definir a página para acessar e permitir ao usuário gravar e excluir produtos.

Antes de iniciar temos que definir uma referência ao projeto BLL que criamos pois a camada de interface precisa enxergar a camada de negócio para ter acesso às classes nela criadas.

Clique com o botão direito sobre o projeto WEB e selecine Add Reference;

A seguir na janela Add Reference selecione o projeto BLL e clique em OK;

Outra providência importante que devemos tomar e copiar a string de conexão (Entity Connection) do arquivo App.Config da camada DAL para o arquivo web.config da nossa camada de interface, o projeto WEB;

O arquivo Web.config do proejto WEB deverá possuir a seguinte a seção <connectionStrings> definida conforme a seguir:

<configuration>
<system.web>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.0" />
</system.web>
<connectionStrings>
<add name="MacorattiEntities" connectionString="metadata=res://*/Macoratti.csdl|res://*/Macoratti.ssdl|res://*/Macoratti.msl;provider= _
System.Data.SqlClient;provider connection string=&quot;Data Source=.\SQLEXPRESS;Initial Catalog=Macoratti;Integrated Security=True; _
MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" />
</connectionStrings>
</configuration>

Agora vamos incluir um novo formulário no projeto selecionando no menu Project a opção Add New Item e escolhendo o template Web-> Web Form e informando o nome Index.aspx e clicando em Add;

Vamos incluir na página Index.aspx uma tabela via menu Table->Insert Table com 6 linhas e 2 colunas e incluir na página os seguintes controles a partir da ToolBox:

O leiaute da página deverá ser o seguinte:

A próxima etapa é definir o código associado ao code-behind no arquivo Index.aspx.vb começando com o evento Load da página Index.aspx.

Defina no evento Load da página o seguinte código:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Not Page.IsPostBack Then
            carregaCategorias()
            carregaDadosGrid()
        End If
    End Sub

Este código chama as rotinas as seguintes rotinas:

O código da rotina CarregaCategorias é exibido a seguir:

Private Sub carregaCategorias()

        Dim categorias As New Categoria_BLL

        ddlCategorias.DataTextField = "categoriaNome"
        ddlCategorias.DataValueField = "categoriaid"
        ddlCategorias.DataSource = categorias.GetAll
        ddlCategorias.DataBind()
        categorias = Nothing

    End Sub

Neste código estamos usando o método GetAll do contexto categorias definido na camada de negócios Categoria_BLL;

O código da rotina carregaDadosGrid() é o seguinte:

Private Sub carregaDadosGrid()
        Dim categoriaID As Integer = 0
        categoriaID = ddlCategorias.SelectedValue

        Dim produtos As New Produto_BLL
        gdvDados.DataSource = produtos.produtosCategoria(categoriaID)
        gdvDados.DataBind()
        produtos = Nothing
    End Sub

O código acima obtém o ID da categoria a partir da categoria selecionada e após criar uma instância da classe Produto_BLL usa o método produtosCategoria() definido na classe Produto_DAL (lembre que a classe Produto_BLL herda da classe Produto_DAL)

A seguir temos o código associado ao evento SelectedIndexChanged do dropdownlist ddlCategorias que atualiza o controle GridView da página;

Protected Sub ddlCategorias_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) Handles ddlCategorias.SelectedIndexChanged
        carregaDadosGrid()
    End Sub

No evento Click do botão Salvar chamamos a rotina salvarProduto();

Protected Sub btnSalvar_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnSalvar.Click
        salvarProduto()
    End Sub

O código da rotina salvarProduto é dado a seguir:

Private Sub salvarProduto()
        Dim produtos As New Produto_BLL
        If produtos.procuraProdutoNome(txtNomeProduto.Text).Count > 0 Then
            MsgBox("Ja existe produto cadastrado com esse nome.")
        Else
            Dim produto = produtos.getProduto
            produto.produtonome = txtNomeProduto.Text
            produto.categoriaid = ddlCategorias.SelectedValue
            produtos.Add(produto)
            produtos.SaveChanges()
            carregaDadosGrid()
        End If
    End Sub

Este código é muito importante e nele criamos uma instância da classe Produto_BLL e criamos uma instância de um produto através do método getProduto;

Em seguida atribuímos o nome do produto e o código da categoria e usamos o método Add do contexto produtos para incluir o objeto no contexto;

Para efetivar as informações usamos o método SaveChanges() ;

O evento RowDeleting obtém o código e o nome do produto definido em DataKeyNames() que é uma propriedade do controle GridView() e em seguida chama a rotina deletarProduto(id,nome) para excluir o produto selecionado;

A propriedade DataKeyNames obtém ou define uma matriz que contém os nomes dos campos de chave primária para os itens exibidos em um GridView, assim ao selecionar um item podemos obter os valores definidos nesta propriedade.

Protected Sub gdvDados_RowDeleting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewDeleteEventArgs) Handles gdvDados.RowDeleting
        'obtem o codigo do produto no DataKeyNames
        Dim id As Integer = CType(gdvDados.DataKeys(e.RowIndex)(0).ToString, Integer)
        'obtem o nome do produto definido no DataKeyNames
        Dim nome As String = gdvDados.DataKeys(e.RowIndex)(1).ToString()
        deletarProduto(id, nome)
        carregaDadosGrid()
    End Sub	

O código da rotina deletarProduto() é exibido abaixo:

Private Sub deletarProduto(ByVal codigoProduto As Integer, ByVal nomeProduto As String)
        Dim produtos As New Produto_BLL

        Dim produto = produtos.getProduto

        produto.produtoid = codigoProduto
        produto.produtonome = nomeProduto
        produto.categoriaid = ddlCategorias.SelectedValue

        produtos.Attach(produto)

        produtos.Delete(produto)
        produtos.SaveChanges()
        carregaDadosGrid()
    End Sub

Nele estamos criando uma instância da classe Produto_BLL e obtemos uma instância de um produto através do método getProduto;

A seguir atribuímos o código e nome do produto e o código da categoria e usamos o método Attach para anexar o produto ao contexto;

No Entity Framework (EF), objetos podem ser anexados (attached) a ou desanexados (detached) de um contexto. Objetos que são anexados a um contexto são tratados e gerenciados por este contexto.

Objetos desanexados não são referenciados pelo contexto, e seus recursos podem ser requisitados pelo .NET Framework.

Obs: O conceito de contexto mencionado aqui esta relacionado com o ObjectContext gerado pelo Entity Framework (EF).

É importante compreender estes conceitos para evitar dor de cabeça quando formos trabalhar com o Entity Framework (EF).

Em seguida usamos o método Delete para excluir o produto e método SaveChanges() para efetivar a exclusão;

Lembrando que os métodos Delete e SaveChanges foram definidos na interface base IBaseCrud e implementados na classe Abstract_Crud();

Executando a aplicação web vemos a inclusão de um produto Teste;

A seguir estamos selecionando o produto e excluindo;

Após confirmação vemos a exclusão efetivada;

Dessa forma mostramos como implementar a manutenção de dados com funções para incluir e alterar usando o Entity Framework em camadas.

Pegue o projeto completo aqui : EF_CRUD.zip

Eu sei é apenas Entity Framework, mas eu gosto...

Referências:

José Carlos Macoratti