Entity Framework – Data Annotations

O Entity Framework (EF) permite que utilizemos nossas classes para construção e mapeamento de nosso banco de dados, para tanto algumas convenções são necessárias para que ocorra o mapeamento. Mas muitas vezes as convenções não são suficientes, pois em determinados cenários a representação de nossas classes não é a mesma representação de nosso banco de dados. Este post objetiva apresentar o uso de DataAnnotations (atributos de mapeamento) presentes no namespace  System.ComponentModel.DataAnnotations para construção de nossas classes. Abaixo seguem alguns dos atributos mais utilizados, seu modo de uso e seu impacto no banco de dados.

Key
As entidades mapeadas pelo Entity Framework precisam de uma propriedade que trabalhe como chave primária (propriedade chave), que trabalhe como “propriedade de rastreamento” do dado dentro da tabela, contendo um valor que diferencie o registro dos demais ali armazenados.  Por convenção, o EF procura em sua classe por uma propriedade nomeada como “Id” ou uma propriedade nomeada com o nome da classe concatenada a palavra “Id” (i.e. ProdutoId, PedidoId, ClienteId). Caso o EF não encontre uma propriedade que esteja dentro de suas convenções, então uma exception será disparada exigindo que a classe possua uma propriedade chave. Caso sua classe não possua uma propriedade cujo nome esteja dentro destas convenções então é possível utilizar o atributo Key para indicar qual propriedade de sua classe deverá funcionar como propriedade chave.

Impacto no banco de dados: será gerada uma primary key com identação automática (identity).

figuraAtributoKey

Required
O atributo Required indica que um atributo em particular é obrigatório e que não poderá deixar de ser valorizado.

Impacto no banco de dados: o uso deste atributo adiciona uma restrição “not null” na coluna gerada no banco de dados.

figuraDataAnnotationRequired

MaxLength e MinLength
Estes atributos validam o tamanho do dado inserido, limitando o tamanho máximo e/ou indicando seu tamanho mínimo.

Impacto no banco de dados: o tamanho das colunas criadas no banco de dados serão limitados pelo uso do atributo MaxLenght. O tamanho default das colunas, sem o uso do atributo MaxLenght, é de 128 caracteres.

figuraMaxLengthMinLength

NotMapped
Existem cenários onde nem todos os atributos de nossas classes devem ser mapeados para o banco de dados. Este cenário existe quando alguma das propriedades de nossa classe é resultante de alguma ação dinâmica ou cálculo, e que não precisa ser armazenada na base de dados.

Impacto no banco de dados: nenhum, esse atributo não acarreta na criação de nenhuma coluna, na verdade ele é ideal para que a coluna não seja criada.

figuraNotMapped

ComplexType
Não é incomum que nossa classes possuam propriedade que sejam instâncias de outros objetos, cujos dados não queremos armazenar em tabelas dedicadas. No nosso exemplo podemos incluir uma propriedade que indique qual o endereço de entrega de um malote, mas talvez não seja necessário possuir uma tabela exclusiva para o armazenamento dos endereços, podemos desejar que nossa tabela de malote possuísse as colunas de endereço dentre suas colunas. Para tanto, devemos utilizar o atributo ComplexType para indicar este cenário. Detalhe, este atributo deve ser incluído na classe que corresponde ao tipo complexo, não na classe que contém o atributo com o tipo complexo.

Impacto no banco de dados: nenhuma nova tabela será criada, em contraponto, as propriedades existentes na classe que  contém o atributo ComplexType serão mapeadas para a tabela que contém a propriedade que utiliza o tipo de dados.

figuraComplexType01

figuraComplexType02

Table and Column
Podem existir dois casos onde os nomes das colunas das tabelas não são os mesmos dos nomes dos atributos das classes,  sendo: o primeiro, quando o banco de dados já existe e é preciso criar o mapeamento para o mesmo; segundo, quando por alguma necessidade do cliente o banco de dados deve possuir uma nomenclatura de acordo com um conjunto de regras e padrões.

O atributo Table permite o mapeamento de uma classe para uma tabela, substituindo as conversões do Entity Framework.

figuraAtributoTable

O atributo Column permite a definição do nome da coluna que será mapeada pelo Entity Framework. No exemplo abaixo é  possível notar que também é possível a combinação de diferentes atributos de mapeamento em uma única propriedade.

figuraAtributoColumn

ForeignKey
O atributo ForeignKey indica qual propriedade na classe representa o campo que corresponde à chave estrangeira entre as tabelas. Note que no exemplo abaixo o atributo ForeignKey está acima da propriedade que representa a navegação entre as duas entidades.

figuraForeignKey

Por
Fernando Henrique Inocêncio Borba Ferreira.

Entity Framework 4.1 + MVC + DAO

Neste exemplo vamos demonstrar o uso dos design patterns MVC e DAO, combinados com a utilização do Entity Framework 4.1 como tecnologia de acesso a dados de nossa aplicação.

O MVC (Model-View-Controller) é um design pattern bastante utilizado no mercado devido a sua capacidade de dividir a aplicação em camadas especialistas em suas funções, favorecendo a alta coesão das mesmas. A camada model é responsável por representar o mundo real através do uso de objetos. A camada view é dedicada exclusivamente a apresentação dos dados, podendo ser uma aplicação web, uma aplicação console, um formulário do Windows, uma page Silverlight, ou qualquer outra tecnologia front-end. A camada controller faz ponte entre a camada view e a camada model, interceptando a comunicação entre as duas e aplicando regras, validações, redirecionamentos ou encapsulando a comunicação com diferentes frameworks e sistemas. Outra vantagem deste modelo é a possibilidade de criar módulos independentes que trabalhem de modo desacoplado, para que se tornem fáceis de serem substituídos e reutilizados.

O design pattern DAO (Data Access Object) tem o objetivo de encapsular todos os acessos as fontes de dados feitas na aplicação. O uso deste design pattern permite que nossa aplicação não fique dependente de uma tecnologia de acesso a dados, pois estaremos agrupando todas as regras e usos de frameworks específicos de acesso a dados em uma única camada que pode ser facilmente substituída. Caso seja necessária a substituição da tecnologia de armazenamento (exemplo: de MS SQL para Oracle, ou de MS SQL para SQL Azure, ou de Oracle para alguma tecnologia NoSQL) o impacto não será tão grande, e a adaptação do sistema será restrita, evitando impactos globais na aplicação.

Mãos a obra

Pare demonstrar o uso destes design patterns e do Entity Framework 4.1 criaremos um cadastro simples de carros e suas respectivas montadoras.

1 – Abra o Microsoft Visual Studio 2010 e crie uma solução em branco.
2 – Adicione um projeto class library, no nosso exemplo este projeto chamará SampleCore.
3 – Apague o arquivo “Class1.cs” que é criado automaticamente pelo Visual Studio. Faça referências ao namespace “System.Data.Entity” e ao Entity Framework 4.1, geralmente esta localizado no caminho C:\Program Files (x86)\Microsoft ADO.NET Entity Framework 4.1\Binaries\EntityFramework.dll, o download do EF 4.1 pode ser feito neste link: http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=8363
4 – Crie três pastas dentro do projeto, chamadas Model, Controller e Data.
5 – Crie as classes Carro e Montadora dentro de Model conforme os exemplos a seguir:

01

02

Observe que para representar o relacionamento um para muitos (entre a montadora e os carros) utilizamos o tipo de dados ObservableCollection. ObservableCollection representa uma coleção de dados dinâmica que fornece notificações quando os itens são adicionados, removidos ou quando toda a lista é atualizada.

6 – Agora vamos começar a trabalhar com nossa camada de acesso a dados. Antes de qualquer coisa, criaremos duas interfaces para nossos repositórios de montadoras e carros. As interfaces devem ser criadas dentro de Model e devem implementar a seguinte estrutura:

03

04

Crie dentro da pasta Data uma classe chamada ContextoBancoDados e faça-a herdar de DbContext (namespace System.Data.Entity dentro do assembly EntityFramework.dll). E implemente-o conforme o código abaixo:

05

Caso o banco de dados não exista, e nenhuma string conexão tenha sido fornececida, então será criada uma base de dados local, cujo nome será igual a assinatura da classe dbcontext, isto é, o namespace da qual a classe pertence concatenado com o nome da classe dbcontext. Por exemplo, se sua classe dbcontext pertencer ao namespace “NomeDoCliente.NomeDoProjeto.Repositorio” e sua classe datacontext se chamar “ContextoBancoDados” então o nome de seu banco de dados será  “NomeDoCliente.NomeDoProjeto.Repositorio.ContextoBancoDados”… Não parece ser uma boa prática um nome deste tamanho com características de nomenclatura tão específicas, então recomendo que sempre seja informada uma string de conexão, como no exemplo anterior.

Obs.: Para este exemplo deixei a string de conexão fixa (“chumbada”) no código… Esta realmente não é uma boa prática, o melhor neste caso é deixar a string de conexão em um arquivo configurável de sua aplicação. Para este cenário procure utilizar recursos nativos, como os arquivos App.Config e Web.Config.

7 – Para garantir a criação de seu banco de dados no primeiro acesso procure deixar fixo em algum lugar estratégico de sua aplicação a chamada para o método de criação da base. Não é uma boa prática tornar esse bloco de criação do banco de dados algo que será sempre validado e executado, pois isso pode consumir tempo e recursos operacionais. Então, como dica, os dois locais que acredito serem os ideais para este tipo de procedimento:
– Evento Application Start do Global.asax – no caso de aplicações web.
– Método Main() do arquivo Program.cs – no caso de aplicações desktop e console.

Mais para frente, neste mesmo post, irei demonstrar os comandos necessários para criação do banco de dados.

8 – Para implementação do design pattern DAO e utilização do Entity Framework 4.1 implementaremos as classes RepositorioMontadora e RepositorioCarro dentro da pasta Data da seguinte forma:

060

070

Para encapsular os comandos de criação do banco de dados, encapsularemos seu comportamento em uma classe chamada BancoDadosRepositorio implementada por uma interface chamada IFonteDadosRepositorio, conforme o código a seguir:

090

080

9 – Agora que temos criadas nossas entidades e nossos repositórios, poderemos implementar nossa classe controller que irá gerenciar os acessos as nossas fontes de dados, além de fazer ponte com nossa camada de visão. Nesta classe, por conta da simplicidade de nosso exemplo, iremos implementar as regras de persistência das montadoras e dos carros no mesmo controller. Da seguinte maneira:

100

10 – Nesses momentos já temos nossa camada de DAO pronta, além das camadas model e controller (pertencentes ao MVC) também concluídas. O próximo passo agora é implementar a camada de visão. Para este exemplo criaremos uma aplicação console, pois no momento a estrutura de nossa aplicação tem maior relevância do que a interface. Nesta demonstração criamos uma aplicação console chamada SampleConsole, e fizemos referência para o projeto SampleCore, para que conseguíssemos acessar suas classes. Nossa aplicação console deverá se parecer com algo como:

110

A estrutura da aplicação deve ficar como a imagem a seguir:

00000

Para fazer o download acesse este link: http://code.msdn.microsoft.com/Entity-Framework-41-MVC-DAO-4860e78c

Por
Fernando Henrique Inocêncio Borba Ferreira.

Entity Framework 4.1

O Entity Framework 4.1 (EF 4.1) é um release que funciona sobre o ADO.Net Entity Framework incluso no .Net Framework 4.0. O EF 4.1 trás como novidade um novo DbContext e oficializa o Code First, antes um projeto paralelo do time de ADO.Net.

O Code First objetiva a configuração do modelo e criação do banco de dados a partir de nossas classes C# ou Visual Basic .Net, e/ou o mapeamento de um banco de dados existente.

Quais as novidades?
DbContext API – A nova classe System.Data.Entity.DbContext é uma versão alternativa ao ObjectContext, e é a classe preferencial para integração com banco de dados.
DbSet – Versão simplificada do ObjectSet, perfeita para fazer CRUD (Create, Retrive, Update e Delete) de um tipo existente do modelo.
ADO.Net DbContext Generator T4 Templates – ferramenta geradora de entidades POCO (Plain-Old CLR Objects).
Validation – O DbContext automaticamente valida entidades antes de salvá-las no banco de dados.
Code First – Code First permite a construção de modelos de bancos de dados através de nossas classes C# e Visual Basic .Net, além da adição de configurações através da atributos nas classes ou configurações no DbContext.

Vamos abordar mais sobre o Entity Framework 4.1 neste espaço nos próximos meses, a fim de ampliar o conhecimento da comunidade sobre essa tecnologia tão fantástica.

Por
Fernando Henrique Inocêncio Borba Ferreira.

Introdução ao Entity Framework Code First CTP 5

O objetivo deste post é apresentar o funcionamento do Entity Framework Code-First CTP 5. Este conjunto de bibliotecas ainda não está disponível na instalação do Visual Studio 2010, nem na instalação do Microsoft .Net Framework 4, pois ainda está em fase de testes e melhorias, por isso que ainda é um CTP (Community Technology Previews). O EF Code-First, apesar de ser um CTP, já está na versão 5, e apresenta muitas facilidades que auxiliam os desenvolvedores de software.

Nas próximas linhas apresentarei um exemplo de como trabalhar com o EF Code-First. Neste exemplo utilizo o conceito POCO (Plain Old CLR Objects), já discutido em um post anterior. Faremos a persistência dos dados de algumas entidades no banco de dados, e o EF Code-First ficará encarregado de fazer o mapeamento objeto-relacional para nossa aplicação.

Para utilizar o Entity Framework Code-First CTP 5 faça o download do mesmo neste link e siga os seguintes passos:

1 – Crie as tabelas no banco de dados Microsoft SQL Server, conforme o script abaixo:

POCO_SQL

2 – No Visual Studio 2010, crie uma solution em branco. Para este exemplo criei uma solution com o nome “SolutionEF_CTP5”.

3 – Adicione um projeto Class Library a solution. Para este projeto utilizei o nome “EFCTP5.Data”.

4 – Crie as classes Cliente, Endereco, Solicitacao conforme o código abaixo:

POCO_CLIENTE

POCO_ENDERECO

POCO_SOLICITACAO

5 – Após a adição destas classes, faça referências as DLLs:

  • System.Data.Entity
  • EntityFramework
    (geralmente localizada em C:\Program Files (x86)\Microsoft ADO.NET Entity Framework Feature CTP5\Binaries\)
  • System.Configuration

6 – Criar a classe de contexto, que irá administrar as requisições com a base de dados. Faça esta classe herdar de DbContext (System.Data.Entity). Adicione propriedades para representação das tabelas utilizando o tipo de dados DbSet – este tipo de dados é próprio para representação de coleções e entidades que podem servir para construção de queries. Sobrescreva o método “OnModelCreating”, com o objetivo de evitar a convenção de que o nome das tabelas devem estar no plural (pluralizados). Adicione um bloco de código no construtor desta classe para que a string de conexão seja preenchida sempre que o contexto de banco de dados for instanciado.

POCO_CONTEXT

8 – Criei um projeto console para testar a aplicação e adicione referência ao projeto criado anteriormente e a DLL do Entity Framework  Code First CTP 5.

POCO_ESTRUTURA

9 – Adicione um arquivo “App.Config” ao projeto e insira o seguinte bloco de configuração atribuindo uma string de conexão para o seu banco de dados:

POCO_STRING DE CONEXAO

10 – Adicione o código abaixo, na aplicação console, para testar a inclusão de novos registros.

POCO_INSERT

11 – Adicione o código abaixo, na aplicação console, para a consulta de registros cadastrados na base de dados.

POCO_SELECT

[]s! e até o próximo…

Utilizando ADO.Net POCO Entity Generator

Uma nova abordagem de mapeamento objeto-relacional é o POCO (Plain Old CLR Object), que permite a utilização de nossas próprias classes como entidades dentro do modelo de mapeamento. Esta abordagem preza a utilização de classes simples, que não façam referência a frameworks especializados, que não dependam de soluções de terceiros, que não implementem nenhuma interface especial e que não dependam de nenhuma hierarquia de namespace.

O ADO.Net POCO Entity Generator é um template do Visual Studio 2010 que auxilia na construção de projetos que adotem o POCO criando entidades a partir de um modelo de dados. Neste post veremos quais os passos necessários para adoção desta técnica em projetos e como utilizar este template do Visual Studio 2010.

1 – Crie a tabela Person no banco de dados, conforme o script SQL abaixo:

clip_image002

2 – Crie uma solution no Visual Studio 2010 em branco.

clip_image004

3 – Adicione dois projetos Class Library a solution, a estes novos projetos atribua os nomes Data e Entities.

clip_image006

4 – Selecione o projeto Data e adicione um novo item utilizando o template ADO.Net Entity Data Model. No exemplo, criei com o nome dbModel.edmx. Este item é aquele comumente utilizado para adições de mapeamentos objeto-relacionais através do Entity Framework. Nas telas seguintes devem ser definidas: a conexão com o banco de dados e as tabelas que serão mapeadas. Neste exemplo apenas mapeei a tabela Person.

clip_image008
clip_image010

5 – Após fazer o mapeamento utilizando o Entity Framework, será preciso instalar o template ADO.Net POCO Entity Generator (caso o mesmo não esteja instalado). Clique em “Tools/Extension Manager”, selecione a aba Online Gallery e na caixa de pesquisa (localiza no canto superior direito) e pesquise por “T4”. Após a exibição dos resultados, instale os templates: “ADO.Net C# POCO Entity Generator” e “ADO.Net C# Web Site POCO Entity Generator” (caso a sua linguagem preferida seja VB.Net, então instale os templates próprios para a mesma, eles também estão disponíveis no resultado da consulta feita anteriormente).

clip_image012

clip_image014

6 – Após o download dos templates, volte a ferramenta de mapeamento, clique com o botão direito sobre uma das entidades mapeadas e seleciona a opção “Add Code Generation Item”.
clip_image016
7 – Adicione um novo item utilizando o template ADO.Net POCO Entity Generator. Neste exemplo atribui o nome “ModelPoco.tt”.

clip_image018

8 – Serão criados dois arquivos “ModelPoco.Context.tt” e “ModelPoco.tt”. O arquivo “ModePoco.tt” constrói as entidades, enquanto que o arquivo “ModelPco.Context.tt” gera o contexto tipado. Mova o arquivo “ModePoco.tt” Para o projeto Entities, a fim deixar o projeto classe projeto com suas respectivas responsabilidades separadas, sendo: Data, com acesso aos dados e o Entities, representando as entidades. Adicione no projeto Data referência para o projeto Entities.

clip_image020

9 – Dentro de “Modelo.tt”, na linha 22, altere o caminho do arquivo de mapeamento do Entity Framework para “..\Data\dbModel.edmx”. Isso fará com que a geração das entidades aponte para o arquivo correto, já que mudamos o arquivo de projeto.

clip_image022

Dentro de “ModelPoco.Context.tt”, vá até a linha 44, adicione uma referência para Entities, para que a geração de estruturas POCO possa identificar os tipos de dados utilizados no contexto.

clip_image024

Acesse as propriedades do arquivo “ModelPoco.tt” e altere a propriedade Custom Tool Namespace para “Entities”, faça o mesmo para o arquivo “ModelPoco.Context.tt”, mas modifique o valor da propriedade Custom Tool Namespace para “Data”. Esse passo é importante para que a geração de dados seja feita utilizando os namespaces previstos.

10 – Para testar o código, dentro da solution, crie um novo projeto utilizando o template Console Application. Dentro deste novo projeto faça referência as DLLs: Data, Entities e System.Data.Entity. Copie o arquivo “App.Config” que está localizado no projeto Data para este novo projeto, este passo é importante pois a string de conexão está localizada no mesmo.

clip_image026

11 – Para inserir novos registros utilize o código a seguir:

clip_image028

12 – Para consultar dados da base de dados utilize o código a seguir:

clip_image030

[]s! e até o próximo…

 

Por
Fernando Henrique Inocêncio Borba Ferreira.