Entity
Framework
6 -
Carregando Entidades e
Propriedades de Navegação
![]() |
Neste artigo vamos abordar as opções disponíveis para carregar dados relacionados no Entity Framework 6 mostrando os prós e contras de cada opção. Vamos tratar os comportamentos Lazy Loading e Eager Loading com exemplos e discutir em quais situações qual a abordagem é mais indicada. |
O Entity Framework(EF) fornece um ambiente que permite ao desenvolvedor trabalhar visualmente com classes de entidades que são mapeadas para tabelas, views, stored procedures e relacionamentos de um banco de dados relacional.
O comportamento padrão do EF é carregar somente as entidades diretamente necessárias pela sua aplicação, e, de forma geral, é este comportamento que você deseja. Se o EF carregasse todas as entidades relacionadas através de uma ou mais associações, você provavelmente, carregaria mais entidades do que precisa, impactando a memória usada e o desempenho de sua aplicação.
Você pode controlar quando a carga de entidades relacionadas ocorre e assim otimizar o número de consultas executadas contra o banco de dados. Gerenciando com cuidado se, e quando as entidades relacionadas são carregadas, você pode aumentar o desempenho de sua aplicação e obter um maior controle sobre os seus dados.
Vamos começar falando sobre o comportamento padrão do EF, o Lazy Loading.
Lazy Load é o mecanismo utilizado pelos frameworks de persistência para carregar informações sob demanda. Esse mecanismo torna as entidades mais leves, pois suas associações são carregadas apenas no momento em que o método que disponibiliza o dado associativo é chamado.
Assim quando objetos são retornados por uma consulta, os objetos relacionados não são carregados ao mesmo tempo, ao invés, eles são carregados automaticamente quando a propriedade de navegação for acessada.
Recursos usados
Definindo o modelo de dados
Neste artigo eu vou usar o Entity Framework 6 e a abordagem DataBase First e neste caso vamos usar o banco de dados Macoratti.mdf do SQL Server 2012 Express.
Podemos usar as seguintes abordagem com o Entity Framework :
1 - Code First - Criamos classes POCO que são mapeadas para as entidades;
2 - Database First - Mapeamos para um Banco de dados que já existe;
3 - Model First - Criamos o Modelo conceitual primeiro e depois é gerado o script para criar o banco de dados;
|
Neste banco de dados vamos usar as tabelas Clientes, ClienteTipos e ClienteEmails que possuem as seguintes estruturas:
![]() |
Clientes |
![]() |
ClienteTipos |
![]() |
ClienteEmails |
Temos aqui um relacionamento Um-para-Muitos entre a tabela Clientes e ClienteEmails e entre a tabela ClienteTipos e Clientes:
Criando o Entity Data Model
Abra O Visual Studio 2013 Express for Windows desktop e clique em Visual Studio Solutions e a seguir em Blank Solution;
Informe o nome da solução como EF6_LazyLoading e clique no botão OK;
Agora vamos criar um novo projeto em nossa solução. Clique no menu FILE e a seguir em Add -> New Project;
Selecione a linguagem Visual Basic e o template Console Application e informe o nome EF6_LazyLoadDemo.
Vamos criar um Entity Data Model no projeto Console. Selecione o projeto e Clique em PROJECT -> Add New Item;
Selecione a guia Data e o template ADO .NET Entity Data Model, informe o nome Macoratti e clique no botão Add;
![]() |
No assistente selecione a opção EF Designer from database e clique no botão Next>;
Selecione a conexão com o banco de dados Macoratti.mdf (Se ele ainda não existir clique em New Connection e defina a conexão);
Aceite as configurações do assistente que salva a string de conexão no arquivo App.Config e cria o contexto MacorattiEntities;
Clique no botão Next>;
Selecione a opção Entity Framework 6.x e clique no botão Next>;
A seguir selecione as tabelas do banco de dados e marque as opções conforme a figura abaixo clicando no botão Finish para concluir essa etapa:
Será gerado o modelo de entidades conforme a figura abaixo:
Temos aqui as entidades Cliente, ClienteTipo e ClienteEmail mapeadas para as respectivas tabelas.
Note que no Entity Data Model - Cadastro.edmx podemos ver as classes :
Do contexto - Macoratti.Context.cs
Das entidades - Cliente.vb, ClienteTipo.vb e ClienteEmail.vb
Carregando dados de navegação : Lazy Loading e Eager Loading
Agora vamos definir o código no Módulo do projeto console conforme mostrado abaixo:
Module Module1
Sub Main()
Using context = New MacorattiEntities()
Dim clientes = context.Clientes
Console.WriteLine("Somente informação dos clientes")
Console.WriteLine("======================================")
For Each cliente In clientes
Console.WriteLine("O nome do cliente é : {0}", cliente.clienteNome)
Next
Console.WriteLine("")
Console.WriteLine("")
Console.WriteLine("Solicitando informação de entidades relacionadas")
Console.WriteLine("clienteTipoDescricao e clienteEmail")
Console.WriteLine("O EF gera consultas separadas para cada entidade")
Console.WriteLine("======================================")
For Each cliente In clientes
Console.WriteLine("{0} é um cliente {1}, seu(s) email(s) : ", cliente.clienteNome, cliente.ClienteTipos.clienteTipoDescricao)
For Each email In cliente.ClienteEmails
Console.WriteLine(vbTab & "{0}", email.clienteEmail)
Next
Next
Console.WriteLine("")
Console.WriteLine("")
Console.WriteLine("Nesta consulta a consulta não vai ser feita no banco de dados ")
Console.WriteLine("O EF irá retornar os dados relacionados da memória feita na consulta anterior ")
Console.WriteLine("======================================")
For Each cliente In clientes
Console.WriteLine("{0} é um cliente {1}, seu(s) email(s) ", cliente.clienteNome, cliente.ClienteTipos.clienteTipoDescricao)
For Each email In cliente.ClienteEmails Console.WriteLine(vbTab & "{0}", email.clienteEmail) Next Next End Using Console.ReadKey()
End Sub
End Module
|
Executando este código iremos obter o seguinte resultado:
A seguir temos a versão deste código para linguagem C# :
public static void Main()
{
using (context == new MacorattiEntities())
{
var clientes = context.Clientes;
Console.WriteLine("clientes");
Console.WriteLine("=========");
foreach (var cliente in clientes)
{
Console.WriteLine("O nome do cliente é : {0}", cliente.clienteNome);
}
foreach (var cliente in clientes)
{
Console.WriteLine("{0} é um cliente {1}, seu(s) email(s) : ", cliente.clienteNome, cliente.ClienteTipos.clienteTipoDescricao);
foreach (var email in cliente.ClienteEmails)
{
Console.WriteLine("\t{0}", email.clienteEmail);
}
}
foreach (var cliente in clientes)
{
Console.WriteLine("{0} é um cliente {1}, seu(s) email(s) ", cliente.clienteNome, cliente.ClienteTipos.clienteTipoDescricao);
foreach (void email in cliente.ClienteEmails)
{
Console.WriteLine("\t{0}", email.clienteEmail);
}
}
}
}
|
Agora vamos entender como isso funciona :
- Por padrão o EF carrega somente as entidades que você requisita. Isso é conhecido como lazy loading;
- A alternativa ao lazy loading é conhecida como eager loading e consiste em carregar a entidade pai e cada entidade associada a ela;
- A abordagem eager loading pode carregar uma grande quantidade de objetos na memória causando impactando o desempenho da sua aplicação;
- Neste exemplo começamos executando uma consulta contra a entidade Clientes para carregar todos os clientes:
Dim clientes = context.Clientes
Console.WriteLine("Somente informação dos clientes")
Console.WriteLine("======================================")
For Each cliente In clientes
Console.WriteLine("O nome do cliente é : {0}", cliente.clienteNome)
Next
Esta consulta não é executada imediatamente; ele é executada quando enumeramos a entidade cliente na laço foreach (cliente.ClienteNome) . Esse comportamento é conhecido como princípio da execução deferida.
Na primeira construção do foreach, estamos solicitando dados apenas da tabela Clientes. Não solicitamos dados das demais tabelas. Neste caso o EF somente consulta a tabela Clientes.
Na segunda consulta estamos explicitamente referenciando a propriedade clienteTipoDescricao da entidade ClienteTipos e a propriedade ClienteEmail da entidade ClienteEmails:
For Each cliente In clientes
Console.WriteLine("{0} é um cliente {1}, seu(s) email(s) : ", cliente.clienteNome, cliente.ClienteTipos.clienteTipoDescricao)
For Each email In cliente.ClienteEmails
Console.WriteLine(vbTab & "{0}", email.clienteEmail)
Next
Next
Acessando diretamente essas propriedade faz com que o EF gere uma consulta para cada tabela relacionada para requisitar os dados.
É importante você entender que o EF neste caso gera uma consulta separada na primeira vez que as tabelas relacionadas são acessadas.
Uma vez que a consulta tenha sido chamada para uma propriedade de uma entidade relacionada, o Entity Framework vai marcar a propriedade como carregada e irá recuperar os dados da memória na próxima execução.
Esta consulta separada para cada tabela funciona bem quando um usuário está navegando em seu aplicativo e requisitando diferentes elementos de dados, dependendo das suas necessidades no momento. Ela pode melhorar o tempo de resposta das aplicações, uma vez que os dados são recuperados, conforme necessário, com uma série de pequenas consultas, em oposição ao carregar um grande volume de dados, e potencialmente causar um atraso no processamento da massa de dados.
Esta abordagem não é adequada quando você precisa de uma grande quantidade de dados das tabelas relacionadas. Neste caso, a abordagem eager loading é melhor pois ela retornar todos os dados em uma única consulta.
A última
consulta demonstra que uma vez que uma propriedade filha seja carregada o EF irá
retornar os valores da memória e não irá fazer a mesma consulta contra o banco
de dados:
For Each cliente In clientes
Console.WriteLine("{0} é um cliente {1}, seu(s) email(s) ", cliente.clienteNome, cliente.ClienteTipos.clienteTipoDescricao)
For Each email In cliente.ClienteEmails
Console.WriteLine(vbTab & "{0}", email.clienteEmail)
Next
Next
Na próxima parte do artigo irei mostrar como salvar dados de entidades relacionadas.
Na
palavra da verdade, no poder de Deus, pelas armas da justiça, à direita e à
esquerda,
Por honra e por desonra, por infâmia e por boa fama; como enganadores, e sendo
verdadeiros;
Como desconhecidos, mas sendo bem conhecidos; como morrendo, e eis que vivemos;
como castigados, e não mortos;
Como contristados, mas sempre alegres; como pobres, mas enriquecendo a muitos;
como nada tendo, e possuindo tudo.
2 Coríntios 6:7-10
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? |
Gostou ?
Compartilhe no Facebook
Compartilhe no Twitter
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Cadastro de Clientes com Entity Framework em - Macoratti.net