Entity Framework - Tarefas básicas : Filtrando dados


O assunto de hoje é como filtrar dados usando o Entity Framework no Visual Basic 2010 Express Edition.

Para começar eu vou criar um novo projeto no Visual Basic 2010 Express Edition, sim ele suporta o Entity Framework, e, aqui eu quero chamar a sua atenção para o fato de você ter uma ferramenta gratuita com esse recurso disponível onde você pode criar projetos avançados e usar sem ter que pagar nada por isso.

No menu File selecione New -> Project e a seguir escolha o modelo Windows Forms Application e informe o nome EntityFramework_FiltrandoDados e clique em OK;

Será criado um projeto com o formulário form1.vb;

Agora eu vou adicionar um novo projeto para isso selecione no menu File -> Add -> New Project e escolha o modelo Class Library informando o nome Entidades e clicando em OK;

Pronto agora temos uma solução com dois projetos conforme exibe a figura abaixo:

Para mostrar algumas das possibilidades de filtrar dados primeiro eu vou gerar o modelo conceitual de dados que também é conhecido com Entity Data Model (EDM).

O EDM é um modelo entidades - relacionamentos onde:
  • Entidades - são instâncias de tipos de entidades como Clientes, Produtos os quais estão estruturados em registros e chaves;
  • Relacionamentos - são instâncias de tipos de relacionamentos que são associações entre dois ou mais tipos de entidades;

É a partir do modelo de entidades que podemos escrever código usando as diferentes APIs, como o provedor EntityClient ou o Object Services com LINQ to Entities.

Para melhor compreendermos os conceitos relacionados com a EDM, podemos separá-los em dois conjuntos:

  • Conceitos para definição de tipos ou estruturas;
  • Conceitos para gerenciamento de instâncias destes tipos;

Essa etapa é a mais importante pois nela serão geradas as entidades e o mapeamento OR/M entre as tabelas e as entidades.

A maneira mais simples de fazer isso é usar o assistente do Entity Data Model (EDM) da seguinte forma:

Selecione o projeto no qual você deseja gerar o Entity Data Model, geralmente criamos um projeto do tipo Class Library para gerar o EDM. No nosso exemplo iremos fazer isso no projeto Entidades;

No menu Project selecione Add New Item;

A seguir selecione o item ADO .NET Entity Data Model e informe o nome dado ao modelo, geralmente esse nome esta relacionado com a fonte de dados que você vai usar, e no meu caso eu vou usar o banco de dados Northwind.mdf criado no SQL Server, então eu deveria informar Northwind.edmx mas eu vou usar o nome Macoratti.edmx;

A seguir clique em Add;

Na próxima janela você deve escolher se deseja gerar o modelo conceitual a partir de um banco de dados já existente ou se vai criar o banco de dados a partir do modelo. Como eu vou usar um banco de dados que já esta criado vou escolher a opção : Generate from database e clicar em Next>;

A próxima janela do Assistente vai permitir que você escolha o banco de dados, e dependo dos provedores instalados, poderemos usar o SQL Server, MySQL, Oracle, etc.

No exemplo eu selecionei o banco de dados Northwind.mdf que já existia. Observe que existe uma string chamada Entity Connection que contém informações sobre a conexão e referência a arquivos .CSDL, MLS e .SSDL e que a opção para salvar a entity connection no arquivo de configuração esta marcada;

O Entity Data Model é um conceito, e o Entity Framework possui uma implementação particular deste modelo que é percebida como
um arquivo EDMX em tempo de desenvolvimento. Em tempo de execução, o arquivo EDMX é tratado em três arquivos XML
separados cada um com um papel definido:
  • .CSDL(Conceptual Schema Definition Language) - (camada conceitual) responsável pelo modelo conceitual;
  • .MLS (Mapping Specification Language) - (camada de mapeamento) responsável pelo mapeamento;
  • .SSDL(Store Schema Definition Language) - (camada de armazenamento) responsável pela persistência;

Abaixo temos as opções usadas no exemplo:

A próxima janela do Assistente permite que você selecione as tabelas a partir das quais vai gerar o modelo conceitual e o mapeamento objeto relacional.

Eu vou selecionar as tabelas : Categories, Customers, Orders, Orders Details e Products;

O nome do modelo é sugerido e eu vou aceitar o nome NorthwindModel mas poderia mudar o nome se desejasse;

Agora basta clicar em Finish para gerar o modelo e gerar o mapeamento que pode ser visto na figura abaixo selecionando o arquivo Macoratti.edmx no projeto Entidades:

Observe que na janela de Propriedades podemos ver o nome do Container e do modelo gerados e no descritor vemos as entidades e as associações entre as mesmas que representam as tabelas selecionadas do banco de dados.

Se você abrir o arquivo App.Config irá observar a string de conexão - entity connection - gerada:

<connectionStrings>
<add name="NorthwindEntities" connectionString="metadata=res://*/Macoratti.csdl|res://*/Macoratti.ssdl|res://*/Macoratti.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=.\SQLEXPRESS;AttachDbFilename=C:\dados\NORTHWND.MDF;Integrated Security=True;Connect Timeout=30;User Instance=True;MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" />
</connectionStrings>

Com isso já temos tudo pronto para usar o Entity Framework em nosso projeto Windows Forms.

Selecionando uma entidade

Para podermos acessar as entidades do modelo e permitir a exibição no projeto Windows Forms vamos primeiro criar uma classe no projeto Entidades chamada EntitiesHelper que irá conter os métodos de acesso as entidades;

No menu Project selecione Add Class e informe o nome EntitiesHelper.vb;

A seguir vamos definir o código abaixo nesta classe:

Public Class EntitiesHelper

    Dim contexto As New NorthwindEntities
    Public Function getClienteByCodigo(ByVal oCliente As Customer) As Customer
       Try
             Dim cliente = (From c In contexto.Customers Where c.CustomerID = oCliente.CustomerID Select c).Single
            
 Return cliente
       Catch ex As Exception
              Throw ex
        End Try
    End Function
End Class

A seguir no projeto Windows Forms vamos definir a interface no formulário form1.vb contendo os controles: ListBox, TextBox e Button conforme o leiaute abaixo:

A seguir no formulário form1.vb defina o código abaixo:

Imports Entidades
Public Class Form1

    Dim ctx As New EntitiesHelper

    Private Sub btnProcessar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnProcessar.Click
       Try
             Dim cliente As New Customer
             Dim cod As String = txtCodigoCliente.Text
             cliente.CustomerID = cod
             cliente = ctx.getClienteByCodigo(cliente)
             exibedados(cliente)
       Catch ex As Exception
              MessageBox.Show("Erro ao acessar dados do cliente : "
& ex.Message)
        End Try
    End Sub

    Private Sub exibedados(ByVal cliente As Customer)
        lstResultado.Items.Add(cliente.CustomerID
& " -" & cliente.ContactName)
    End Sub
End Class

O código cima primeiro define um import ao projeto Entidades;

No evento click do botão Processar criarmos uma instância da classe Cliente e obtemos o código do cliente informado, atribuindo em seguida ao objeto cliente instanciado;

Em seguida chamamos o método getClienteByCodigo() passando o objeto cliente como parâmetro;

A rotina exibedados() é usada para exibir as informações do cliente no controle ListBox;

Executando o projeto iremos obter:

Selecionando mais de uma entidade

Se precisarmos obter uma coleção de clientes podemos definir mais um método na classe EntitiesHelper() que retorna uma coleção.

Vamos supor que desejamos obter os clientes para uma determinada cidade. Neste caso devemos definir um novo método na classe EntitiesHelper() conforme abaixo:

 Public Function getClientesbyCidade(ByVal cidade As String) As List(Of Customer)
        Try
            Dim clientes = contexto.Customers.Where(Function(cliente) cliente.City = cidade)
            Return clientes.ToList
        Catch ex As Exception
            Throw ex
        End Try
    End Function

Neste código estamos usando uma expressão lambda onde passamos o nome da cidade como parâmetro e retornamos uma lista de clientes.

Para exibir os clientes no projeto Windows vamos incluir um novo formulário no projeto: Project -> Add Windows Forms , aceitando o nome padrão form2.vb;

Em seguida inclua no formulário um controle DataGridView (gdvClientes) , um controle Combobox (cboCidades) e uma Label conforme a figura abaixo:

Na propriedade Items da combobox informe o nome de algumas cidades:

London, Madri, Sao Paulo, Campinas, Berlin

obs: Como exercício você pode preencher a combo via código

A seguir vamos definir o código abaixo no formulário form2.vb no evento SelectedIndexChanged de forma que quando uma cidade for escolhida no controle Combobox o código seja executado:

Imports Entidades
Public Class Form2

    Dim ctx As New EntitiesHelper
    
    Private Sub cboCidades_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboCidades.SelectedIndexChanged
        Try
            Dim clientes As New List(Of Customer)
            Dim cidade As String = cboCidades.Text
            clientes = ctx.getClientesbyCidade(cidade)
            gdvClientes.DataSource = clientes.ToList
        Catch ex As Exception
            MessageBox.Show("Erro ao acessar dados do cliente : " & ex.Message)
        End Try
    End Sub
End Class

O código usa o método getClientesbyCidade() passando o nome da cidade selecionada e retorna uma lista de clientes que é exibida no controle DataGridView conforme abaixo:

Assim realizamos o acesso e aplicamos um filtro aos dados usando somente código VB .NET sem nos preocuparmos com SQL.

Esse é o papel do Entity Framework abstrair o acesso aos dados realizando o mapeamento objeto relacional.

Pegue o projeto completo aqui: EntityFramework_FiltrandoDados.zip

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

Jesus dizia pois aos judeus que criam nele: Se vós permanecerdes na minha palavra, verdadeiramente sereis meus discípulos. E conhecereis a verdade e a verdade os libertará.(João 8:31-32)

Referências:

José Carlos Macoratti