Essa pode ser uma pergunta realmente elementar, mas qual é uma boa maneira de incluir várias entidades filhas ao escrever uma consulta que abrange três níveis (ou mais)?
ou seja, eu tenho 4 mesas: Company
, Employee
, Employee_Car
eEmployee_Country
A empresa tem um relacionamento de 1: m com Funcionário.
O funcionário tem um relacionamento de 1: m com Employee_Car e Employee_Country.
Se eu quiser escrever uma consulta que retorne os dados de todas as 4 tabelas, atualmente estou escrevendo:
Company company = context.Companies
.Include("Employee.Employee_Car")
.Include("Employee.Employee_Country")
.FirstOrDefault(c => c.Id == companyID);
Tem que haver uma maneira mais elegante! Isso é longo e gera SQL horrendo
Estou usando o EF4 com o VS 2010
linq
entity-framework
lazy-loading
Nathan Liu
fonte
fonte
//inside public static class Extensions public static IQueryable<Company> CompleteCompanies(this DbSet<Company> table){ return table .Include("Employee.Employee_Car") .Include("Employee.Employee_Country") ; } //code will be... Company company = context.Companies.CompleteCompanies().FirstOrDefault(c => c.Id == companyID); //same for next advanced method
EF 4.1 a EF 6
Há uma digitação forte
.Include
que permite que a profundidade exigida do carregamento mais rápido seja especificada fornecendo expressões Select à profundidade apropriada:O SQL gerado em ambas as instâncias ainda não é intuitivo, mas parece ter desempenho suficiente. Eu coloquei um pequeno exemplo no GitHub aqui
EF Core
O EF Core possui um novo método de extensão
.ThenInclude()
, embora a sintaxe seja um pouco diferente :De acordo com os documentos, eu manteria o 'travessão' extra
.ThenInclude
para preservar sua sanidade.Informações obsoletas (não faça isso):
O carregamento de vários netos pode ser feito em uma única etapa, mas isso requer uma reversão bastante embaraçosa do backup antes de ir para o próximo nó (NB: Isso NÃO funciona com
AsNoTracking()
- você receberá um erro de execução):Então, eu ficaria com a primeira opção (uma opção Incluir por modelo de profundidade de entidade em folha).
fonte
Você pode encontrar este artigo de interesse, disponível em codeplex.com .
O artigo apresenta uma nova maneira de expressar consultas que abrangem várias tabelas na forma de formas de gráfico declarativas.
Além disso, o artigo contém uma comparação completa de desempenho dessa nova abordagem com as consultas da EF. Essa análise mostra que o GBQ supera rapidamente as consultas EF.
fonte
Como você constrói uma consulta LINQ to Entities para carregar objetos filho diretamente, em vez de chamar uma propriedade Reference ou Load ()
Não há outra maneira - exceto implementar o carregamento lento.
Ou carregamento manual ....
fonte