linq - related - entity lazy loading enable




Entidade do framework linq query Include() várias entidades filhas (3)

Use métodos de extensão . Substitua NameOfContext pelo nome do seu contexto de objeto.

public static class Extensions{
   public static IQueryable<Company> CompleteCompanies(this NameOfContext context){
         return context.Companies
             .Include("Employee.Employee_Car")
             .Include("Employee.Employee_Country") ;
     }

     public static Company CompanyById(this NameOfContext context, int companyID){
         return context.Companies
             .Include("Employee.Employee_Car")
             .Include("Employee.Employee_Country")
             .FirstOrDefault(c => c.Id == companyID) ;
      }

}

Então seu código se torna

     Company company = 
          context.CompleteCompanies().FirstOrDefault(c => c.Id == companyID);

     //or if you want even more
     Company company = 
          context.CompanyById(companyID);

Essa pode ser uma questão realmente elementar, mas qual é uma boa maneira de incluir várias entidades filhas ao escrever uma consulta que abranja TRÊS níveis (ou mais)?

ou seja, eu tenho 4 tabelas: Company , Employee , Employee_Car e Employee_Country

A empresa tem uma relação de 1: m com o 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, estou atualmente escrevendo:

Company company = context.Companies
                         .Include("Employee.Employee_Car")
                         .Include("Employee.Employee_Country")
                         .FirstOrDefault(c => c.Id == companyID);

Tem que haver um jeito mais elegante! Isso é longo e gera uma horrenda SQL

Estou usando o EF4 com o VS 2010



EF 4.1 para EF 6

Há um .Include Fortemente tipado que permite que a profundidade necessária do carregamento ansioso seja especificada, fornecendo Selecionar expressões para a profundidade apropriada:

using System.Data.Entity; // NB!

var company = context.Companies
                     .Include(co => co.Employees.Select(emp => emp.Employee_Car))
                     .Include(co => co.Employees.Select(emp => emp.Employee_Country))
                     .FirstOrDefault(co => co.companyID == companyID);

O Sql gerado em ambas as instâncias ainda não é intuitivo, mas parece suficientemente bom. Eu coloquei um pequeno exemplo no GitHub aqui

Núcleo EF

O EF Core tem um novo método de extensão .ThenInclude() , embora a sintaxe seja ligeiramente diferente :

var company = context.Companies
                     .Include(co => co.Employees)
                           .ThenInclude(emp => emp.Employee_Car)
                      ...

De acordo com os documentos, eu manteria o 'recuo' extra no. .ThenInclude para preservar sua sanidade.

Informações obsoletas (não faça isso):

O carregamento de múltiplos netos pode ser feito em uma única etapa, mas isso requer uma reversão um pouco desajeitada no gráfico antes de ir para o próximo nó (NB: Isso não funciona com o AsNoTracking() - você obterá um erro de runtime):

var company = context.Companies
         .Include(co => 
             co.Employees
                .Select(emp => emp.Employee_Car
                    .Select(ec => ec.Employee)
                    .Select(emp2 => emp2.Employee_Country)))
         .FirstOrDefault(co => co.companyID == companyID);

Então, eu ficaria com a primeira opção (um modelo de profundidade de entidade Incluir por folha).





lazy-loading