VB .NET - Usando o Entity Framework com MySQL no VS 2008 - II


No artigo anterior eu criei o banco de dados no MySQL , a solução no Visual Studio 2008 SP1 e gerei o Entity Data Model (EDM) a partir do banco de dados Cadastro.

Vou continuar mostrando como implementar as operações CRUD contra o banco de dados MySQL usando os recursos do Entity Framework.

Repetindo o final do artigo criamos a interface no projeto ef_interface e agora vamos implementar as funcionalidades citadas.

O leiaute da interface é mostrada abaixo:

Controles do formulário:

 - 3 TextBox

  • txtID
  • txtNome
  • txtValor

 - 5 Buttons

  • btnNovo
  • btnAlterar
  • btnExcluir
  • btnExibir
  • btnSair

- 1 DataGridView

  • gdvProdutos

Todas as funcionalidades serão implementadas através do evento Click dos botões de comando.

Para tornar mais claro o entendimento e ressaltar os recursos do Entity Framework eu vou usar uma sintaxe básica e vou usar o tratamento de erros simplificado através do bloco Try/Catch.

Antes de iniciar devemos declarar o namespace   Imports ef_entities; (Lembre-se que referenciamos o projeto ef_entities)

A seguir devemos declarar duas variáveis objeto que serão instanciadas mais tarde:

Dim cadastroContexto As cadastroEntities
Dim produtoLista As List(Of produtos)

Vou iniciar com a funcionalidade para exibir os dados da tabela Produtos no controle DataGridView - gdvProdutos. A idéia é criar uma rotina chamada exibirProdutos() e chamar esta rotina no evento Load do formulário e no evento Click do botão Exibir, de forma que os dados serão exibidos quando o formulário for carregado e toda vez que o cliente clicar no botão Exibir.

O código da rotina é dado a seguir:

 Private Sub exibirProdutos()

        Try

            cadastroContexto = New cadastroEntities
            produtoLista = New List(Of produtos)

            Dim produtosConsulta = From p In cadastroContexto.produtos.ToList

            gdvProdutos.DataSource = produtosConsulta.ToList

        Catch ex As Exception
            MsgBox("Erro : " & ex.Message)
        End Try

End Sub

Criamos uma instância do nosso modelo de entidades - cadastroEntities (é através que temos acesso aos métodos para persistência.)

Definimos a consulta LINQ onde obtemos todos os produtos cadastrados:  Dim produtosConsulta = From p In cadastroContexto.produtos.ToList

Exibimos os produtos no DataGridView:    gdvProdutos.DataSource = produtosConsulta.ToList

Essa rotina será chamada no evento Load e Click e o código correspondente é dado a seguir:

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        exibirProdutos()
End Sub
Código do evento Load do formulário form1
 
Private Sub btnExibir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExibir.Click
        exibirProdutos()
End Sub
Código do evento Click do botão Exibir

Ao executar o projeto o resultado será a exibição dos produtos conforme a figura abaixo::

Para incluir um novo produto usamos o seguinte código no evento Click do botão Novo:

 Private Sub btnNovo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNovo.Click
        Try
            Dim novoProduto As New produtos
            novoProduto.nome = txtNome.Text
            novoProduto.valor = txtValor.Text
            novoProduto.id = -1
            cadastroContexto.AddToprodutos(novoProduto)
            cadastroContexto.SaveChanges()
            MsgBox("Um novo produto foi incluído")
        Catch ex As Exception
            MsgBox("Erro : " & ex.Message)
        End Try
    End Sub

 

No código acima primeiro criamos uma instância da nossa entidade produtos e em seguida atribuímos os valores informados no formulário ao objeto novoProduto, e, incluímos o novo objeto novoProduto na coleção de objetos :  cadastroContexto.Add(novoAutor)

Você pode incluir novos objetos a um contexto de objeto através do método AddObject ou chamando um dos métodos AddToEntitySetName do ObjectConext.
Você também pode incluir um objeto a um contexto de objeto adicionando o objeto a um EntityCollection existente.
Quando você chama o método Add em um EntityCollection que esta anexada a um contexto de objeto , o objeto que você esta incluindo é adicionado ao mesmo ObjectContext.

Na linha de código  cadastroContexto.AddToAutor(novoAutor) o método AddTo<EntityName>,  que é usado pelo EF baseado nas entidades geradas a partir do banco de dados,e , irá realizar a inclusão do novo objeto no contexto.

O  método SaveChanges() do contexto é usado para persistir as alterações no banco de dados.

Lembre-se que o EF usa o modelo de concorrência otimista e isso significa que não são realizados bloqueios nos dados na fonte de dados. O padrão porém é o Object Services salvar as alterações nos objetos para o banco de dados sem verificar a concorrência.
Havendo uma grande possibilidade de ocorrer concorrência é recomendado que a propriedade da entidade seja definida na camada conceitual com um atributo: 
ConcurrencyMode="fixed"

Ex: <Property Name="Status" Type="Byte" Nullable="false" ConcurrencyMode="Fixed" />

Dessa forma o Object Services irá verificar por alterações no banco de dados antes de salvar as mudanças para o banco de dados e qualquer conflito irá causar uma exceção OptimisticCuncurrencyException.

O código para excluir um produto é dado a seguir:

Private Sub btnExcluir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExcluir.Click

        Try
            cadastroContexto = New cadastroEntities

            Dim p As New produtos
            p.id = txtID.Text

            Dim prod = cadastroContexto.produtos.First(Function(prd) prd.id = p.id)

            cadastroContexto.DeleteObject(prod)
            cadastroContexto.SaveChanges()

            MsgBox("Um produto foi excluido")
        Catch ex As Exception
            MsgBox("Erro : " & ex.Message)
        End Try
    End Sub

O código cria uma instância da nossa entidade produtos e em seguida atribui o valor informado pelo cliente na caixa de texto referente ao código do produto;

Em seguida usamos uma consulta LINQ para localizar a primeira (First) ocorrência cujo código do produto seja igual ao ID informado.

        Dim prod = cadastroContexto.produtos.First(Function(prd) prd.id = p.id)

A seguir o método DeleteObject() marca o objeto para deleção a partir do ObjectStateManager, sendo que o objeto é efetivamente excluído quando o método SaveChanges é chamado.

Para alterar uma informação usamos o seguinte código:

Private Sub btnAlterar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAlterar.Click

        Try
            cadastroContexto = New cadastroEntities
            Dim p As New produtos
            p.id = txtID.Text
            p.nome = txtNome.Text
            p.valor = txtValor.Text

            'localiza o produto a alterar
            Dim prod = cadastroContexto.produtos.First(Function(prd) prd.id = p.id)

            'efetua as alteracoes
            prod.nome = p.nome
            prod.valor = p.valor
            cadastroContexto.SaveChanges()

            MsgBox("Um produto foi alterado")
        Catch ex As Exception
            MsgBox("Erro : " & ex.Message)
        End Try
    End Sub

 

Primeiro criamos uma instância do nosso modelo de entidades - cadastroEntities

A seguir criamos uma instância da nossa entidade produtos e em seguida atribuímos os valores informados no formulário estes valores é que irão alterar os valores originais.

Em seguida usamos uma consulta LINQ para localizar a primeira (First) ocorrência cujo código do produto seja igual ao ID informado.

        Dim prod = cadastroContexto.produtos.First(Function(prd) prd.id = p.id)

A seguir alteramos os valores originais e  usamos o método SaveChanges() do contexto é usado para persistir as alterações no banco de dados.

Além dessa funcionalidades eu criei um tratamento no evento CellClick do controle DataGridView de modo que quando o usuário clicar em uma célula do controle os valores irão preencher as caixas de texto do formulário.  O código é o seguinte:

  Private Sub gdvProdutos_CellClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles gdvProdutos.CellClick
        Dim i As Integer
        Dim j As Integer
        j = gdvProdutos.RowCount - 1
        i = gdvProdutos.CurrentRow.Index
        If i <= j Then
            txtID.Text = gdvProdutos.Item(0, i).Value
            txtNome.Text = gdvProdutos.Item(1, i).Value
            txtValor.Text = gdvProdutos.Item(2, i).Value
        Else
            txtID.Text = ""
            txtNome.Text = ""
            txtValor.Text = ""
        End If
    End Sub

Abaixo temos uma tela exibindo o recurso acima e a funcionalidade para alterar os dados de um produto:



Com isso mostramos como usar o Entity Framework com um banco de dados MySQL no Visual Studio 2008 com SP1. Esse exemplo foi somente um 'tira-gosto' visto que usamos somente uma tabela. Em um cenário mais complexo com relacionamentos, chave estrangeira e herança existem alguns detalhes relativos ao MySQL que deverão ser levados em conta.

Aguarde em breve mais artigos sobre o assunto...

Pegue o projeto completo aqui: EF_MySQL.zip

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

Referências:


José Carlos Macoratti