Chave estrangeira e Associação Independente no Entity Framework

Neste artigo é apresentada a utilização do uso das associações por Foreign Key (Chave Estrangeira) e Independent Associations (Associação independente), demonstrado através de exemplo prático.

Baixe a versão do código demonstrado neste artigo no CodePlex http://efkey.codeplex.com/

Antes de prosseguir com a leitura deste artigo, recomento fortemente que você assista a série de vídeo sobre Entity Frameworks, vai ajudar muito o entendimento deste artigo e o seu aprendizado! Assiste, ajuda! E eu espero :)

  1. ORM, Entity Framework, Linq e Migrations
  2. Refatorando suas classes em Entity Framework
  3. Relacionamento muito-para-muito em Entity Framework
  4. Separando em camadas o Entity Framework

Entity Framework – Independet Associations

Nas primeiras versões do Entity Framework só era possível fazer um único tipo de associação entre as entidades, a Independet Associations, esta primeira abordagem de relacionamento entre as entidades era totalmente orientada a objeto, onde a relação entre dois ou mais objetos é feita através de referencias. Por exemplo, um objeto Produto que possui dentro dele (associação) outro objeto Categoria.

1
2
3
4
5
6
public class Produto
{
public int Id { get; set; }
public string Descricao { get; set; }
public Categoria Categoria { get; set; }
}

O problema deste tipo de associação é que o Entity Framework torna, por vezes, muito complexa a sua implementação, seguindo o raciocínio do exemplo do Produto acima, para adicionar um novo produto, é preciso fazer uma busca nas categorias, achar um objeto categoria e associar ele (com todas as suas dependências/propriedades, no caso a propriedade UnidadeDeMedida) a este produto. E esta complexidade tende a aumentar em objetos muito complexos, que possuam vários outros objetos dentro.

1
2
3
4
5
6
7
8
9
10
11
12
class Program
{
   static void Main()
   {
       var meucontexto = new MeuContexto();
       var produto = new Produto();
       produto.Descricao = "Arroz";
       produto.Categoria = meucontexto.Categorias.Include("UnidadeDeMedida").ToList().FirstOrDefault();
       meucontexto.Produtos.Add(produto);
       meucontexto.SaveChanges();
   }
}

Observe, que foi solicitado ao Entity Framework para incluir na sua busca, a UnidadeDeMedida, que é uma associação que existe entre as Classes Categoria e UnidadeDeMedida, como é demonstrado abaixo.

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Categoria
{
    public int Id { get; set; }
    public string Nome { get; set; }
    public UnidadeDeMedida UnidadeDeMedida { get; set; }
}
 
public class UnidadeDeMedida
{
    public int Id { get; set; }
    public string Descricao { get; set; }
    public string Abreviacao { get; set; }
}

Logo, se tenho uma classe que possui varias associações, é necessário trazer todas estas associações “secundárias” para realizar uma simples associação entre Produto e Categoria.

Entity Framework – Foreign Key

Já no Entity Framework 4 ou superior, o time de desenvolvimento do Entity Framework incluiu um novo tipo de associação onde o modelo conceitual inclui a propriedade do tipo Foreign Key, para definir as associações entre as entidades. Voltando ao nosso exemplo do Produto, agora ao invés de somente ter uma propriedade do tipo Categoria, o objeto Produto teria outra propriedade do tipo int, por convenção, o nome da propriedade Foreign Key é o nome da Propriedade Complexa associada, seguida pelo sufixo Id (no caso CategoriaId), que seria usada como Foreign Key (chave estrangeira), e nesta abordagem, na hora de cadastrar um novo produto, bastaria passar o Id da Categoria, para essa propriedade do tipo int, e a associação estaria feita, o Entity Framework se encarregaria do resto.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Program
{
    static void Main()
    {
        var meucontexto = new MeuContexto();
        var produto = new Produto();
        produto.Descricao = "Arroz";
        produto.CategoriaId = meucontexto.Categorias.ToList().FirstOrDefault().Id;
        meucontexto.Produtos.Add(produto);
        meucontexto.SaveChanges();
    }
}
 
public class Produto
{
    public int Id { get; set; }
    public string Descricao { get; set; }
    public int CategoriaId { get; set; }
    public Categoria Categoria { get; set; }
}

Repare que neste exemplo, não é mais necessário a inclusão da UnidadeDeMedida, que esta associada a categoria, para que se possa criar uma associação entre Produto e Categoria.

Este artigo não tem o propósito de debater os meandros desta abordagem se ela é boa ou não, se quebra ou não as regras da orientação objeto, uma vez que se tem a Foreign Key para fazer associação entre objetos, o próprio time de desenvolvedores do Entity Framework escreveu um artigo sobre isso, que diz que essa decisão deve ser tomada pelo desenvolvedor.

Chave estrangeira e Associação Independente no Entity Framework

Verdade seja dita, o uso de Foreign Key diminui bastante a complexidade do código, o que torna muito mais fácil a manutenção futura, uma vez que não é preciso trazer todo o emaranhado de objetos complexo associadas a uma entidade, para fazer uma simples associação entre esses objetos, sem levar em conta o desempenho nas consultas realizadas para essas associações.

Exemplo completo, para referencia:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
using System;
using System.Data.Entity;
using System.Linq;
 
namespace ChaveEstrangeira
{
    class Program
    {
        static void Main()
        {
            var meucontexto = new MeuContexto();
            var categoria = new Categoria();
            categoria.Nome = "Alimentos";
            categoria.UnidadeDeMedida = new UnidadeDeMedida
                                            {
                                                Abreviacao = "PCT",
                                                Descricao = "Pacote"
                                            };
 
            meucontexto.Categorias.Add(categoria);
            meucontexto.SaveChanges();
 
            var produto = new Produto();
            produto.Descricao = "Arroz";
            produto.CategoriaId = meucontexto.Categorias.ToList().FirstOrDefault().Id;
            //produto.CategoriaId = 1; //Caso saiba o id, basta passar somente o Id.
            meucontexto.Produtos.Add(produto);
            meucontexto.SaveChanges();
 
            //Busca no contexto o produto cadastrado
            var produtoRetornado = meucontexto.Produtos.Include("Categoria").ToList().FirstOrDefault();
            Console.WriteLine(produtoRetornado.Categoria.Nome);
        }
    }
 
    public class Produto
    {
        public int Id { get; set; }
        public string Descricao { get; set; }
        public int CategoriaId { get; set; }
        public Categoria Categoria { get; set; }
    }
 
    public class Categoria
    {
        public int Id { get; set; }
        public string Nome { get; set; }
        public int UnidadeDeMedidaId { get; set; }
        public UnidadeDeMedida UnidadeDeMedida { get; set; }
    }
 
    public class UnidadeDeMedida
    {
        public int Id { get; set; }
        public string Descricao { get; set; }
        public string Abreviacao { get; set; }
    }
 
    public class MeuContexto : DbContext
    {
        public DbSet<Produto> Produtos { get; set; }
        public DbSet<Categoria> Categorias { get; set; }
    }
}

 Para Saber mais assista as vídeo aulas sobre Entity Framework

  1. ORM, Entity Framework, Linq e Migrations
  2. Refatorando suas classes em Entity Framework
  3. Relacionamento muito-para-muito em Entity Framework
  4. Separando em camadas o Entity Framework

Comentarios

comentarios