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.

Publicidade

12 comentários sobre “Entity Framework – Data Annotations

  1. Como Faço para criar uma coluna do tipo DateTime e no banco definir o valor default como “GetDate()” na hora do mapeamento das classes

  2. Olá Pedro,
    Tudo beleza?
    Hoje o EF Code First não tem nenhum recurso para definir o valor padrão dos campos.
    Neste caso, as soluções mais indicadas são duas:
    – no construtor da sua classe settar o valor do seu campo DateTime com um DateTime.Now
    – sobrescrever o método SaveChanges(), identificar as instâncias que estão sendo enviadas para o banco de dados, verificar se a instância é do tipo específico que contém a property DateTime e settar o valor.

    Qualquer coisa é só entrar em contato.
    []s!

  3. Boa tarde,

    Mas na hora de salvar a data será gerada pelo banco de dados ou pela aplicação?
    pode acontecer da data e hora da máquina local ser diferente da hora do servidor.

    Obrigado pela atenção!

    • Olá Pedro,
      A data será a gerada pela aplicação, não pelo banco.
      Se o seu servidor web tiver data diferente do seu servidor SQL, irá prevalecer a data do seu servidor web, pois o seu código esta no servidor web, junto com o EF.

      Obrigado por escrever.

  4. Fernando, existe alguma diferença em mapear com annotation ou fluent api?

    Teria uma forma correta? Ou é só gosto mesmo?
    Você usa qual por exemplo?

    • Olá Rodrigo,
      Sim. Existem muitas diferenças. Alguns exemplos: Quando usamos DataAnnotations o ASP.NET MVC as utiliza durante o processo de validação das páginas, algo que o Fluent API não permite. Outro ponto relevante, o Fluent API contém uma maior gama de recursos que podem ser mapeados, como tipos de relacionamentos entre entidades.

      Não existe uma forma correta, pois ambas são suportadas. Acredito que esteja relacionada a “gosto” (como vc citou) e necessidade técnica.

      Eu gosto mais da Fluent API.

      []s!

  5. Olá, estou tentando criar uma tabela intermediaria, composta por 3 keys de diferentes tabelas, o que necessitaria de chave composta. Você saberia como faz as chaves composta com o EF Code First? Já estou procurando a um bom tempo e até agora sem sucesso.

      • É, realmente tem que usar o Fluente API, agora é tentar descobrir como fazer isso usando ela, só vejo exemplos bem básicos de n-n, usando 2 entidades, com 3 que é o meu caso vou ter que sair testando até dar certo. Obrigado pela ajuda.

Deixe uma resposta para Neto Santos Cancelar resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s

Este site utiliza o Akismet para reduzir spam. Saiba como seus dados em comentários são processados.