Entity Framework: include più livelli di proprietà

Il metodo Include () funziona piuttosto bene per gli elenchi sugli oggetti. Ma cosa succede se ho bisogno di andare a due livelli di profondità? Ad esempio, il metodo seguente restituirà ApplicationServer con le proprietà incluse mostrate qui. Tuttavia, ApplicationsWithOverrideGroup è un altro contenitore che contiene altri oggetti complessi. Posso fare un Include () anche su quella proprietà? O come posso caricare completamente la proprietà?

Così com’è ora, questo metodo:

public IEnumerable GetAll() { return this.Database.ApplicationServers .Include(x => x.ApplicationsWithOverrideGroup) .Include(x => x.ApplicationWithGroupToForceInstallList) .Include(x => x.CustomVariableGroups) .ToList(); } 

Inserirà solo la proprietà Enabled (sotto) e non le proprietà Application o CustomVariableGroup (sotto). Come faccio a far succedere questo?

 public class ApplicationWithOverrideVariableGroup : EntityBase { public bool Enabled { get; set; } public Application Application { get; set; } public CustomVariableGroup CustomVariableGroup { get; set; } } 

Per EF 6

 using System.Data.Entity; query.Include(x => x.Collection.Select(y => y.Property)) 

Vedi Note per altri esempi.

Assicurati di aggiungere using System.Data.Entity; per ottenere la versione di Include che accetta un lambda.


Se si utilizza EF Core, è ansible utilizzare il nuovo metodo ThenInclude

 query.Include(x => x.Collection) .ThenInclude(x => x.Property); 

Se ti capisco correttamente, ti stai chiedendo di includere le proprietà annidate. Se è così :

 .Include(x => x.ApplicationsWithOverrideGroup.NestedProp) 

o

 .Include("ApplicationsWithOverrideGroup.NestedProp") 

o

 .Include($"{nameof(ApplicationsWithOverrideGroup)}.{nameof(NestedProp)}") 

EF Core: utilizzo di “ThenInclude” per caricare i livelli multipli: Ad esempio:

 var blogs = context.Blogs .Include(blog => blog.Posts) .ThenInclude(post => post.Author) .ThenInclude(author => author.Photo) .ToList(); 

Ho fatto un piccolo aiuto per Entity Framework 6 (stile .Net Core), per includere le sotto quadro in un modo piacevole.

Ora è su NuGet: Install-Package ThenInclude.EF6

 using System.Data.Entity; var thenInclude = context.One.Include(x => x.Twoes) .ThenInclude(x=> x.Threes) .ThenInclude(x=> x.Fours) .ThenInclude(x=> x.Fives) .ThenInclude(x => x.Sixes) .Include(x=> x.Other) .ToList(); 

Il pacchetto è disponibile su GitHub .

Ho anche dovuto usare più include e al 3 ° livello avevo bisogno di più proprietà

 (from e in context.JobCategorySet where e.Id == id && e.AgencyId == agencyId select e) .Include(x => x.JobCategorySkillDetails) .Include(x => x.Shifts.Select(r => r.Rate).Select(rt => rt.DurationType)) .Include(x => x.Shifts.Select(r => r.Rate).Select(rt => rt.RuleType)) .Include(x => x.Shifts.Select(r => r.Rate).Select(rt => rt.RateType)) .FirstOrDefaultAsync(); 

Questo può aiutare qualcuno 🙂

Altri esempi di EFCore su MSDN dimostrano che è ansible fare alcune cose abbastanza complesse con Include e ThenInclude .

Questo è un buon esempio di quanto sia complesso ottenere (questa è tutta una dichiarazione!):

 viewModel.Instructors = await _context.Instructors .Include(i => i.OfficeAssignment) .Include(i => i.CourseAssignments) .ThenInclude(i => i.Course) .ThenInclude(i => i.Enrollments) .ThenInclude(i => i.Student) .Include(i => i.CourseAssignments) .ThenInclude(i => i.Course) .ThenInclude(i => i.Department) .AsNoTracking() .OrderBy(i => i.LastName) .ToListAsync(); 

Guarda come puoi concatenare Include anche dopo ThenInclude e questo tipo di ‘resetta’ ti riporta al livello dell’ quadro di livello superiore (Istruttori).

È anche ansible ripetere la stessa raccolta di “primo livello” (CourseAssignments) più volte seguita da comandi ThenIncludes separati per arrivare a diverse quadro figlio.

Nota che la tua query effettiva deve essere taggata alla fine della catena Include o ThenIncludes . Quanto segue NON funziona:

 var query = _context.Instructors.AsQueryable(); query.Include(i => i.OfficeAssignment); var first10Instructors = query.Take(10).ToArray(); 

Ti consigliamo vivamente di configurare la registrazione e assicurarti che le tue query non siano fuori controllo se includi più di una o due cose. È importante vedere come funziona effettivamente e noterai che ciascun “include” separato è in genere una nuova query per evitare enormi join che restituiscono dati ridondanti.

AsNoTracking può velocizzare notevolmente le cose se non intendi davvero modificare le entity framework e salvare nuovamente.

Consentitemi di affermare chiaramente che è ansible utilizzare l’overload di stringhe per includere livelli nidificati indipendentemente dalle molteplicità delle relazioni corrispondenti, se non vi dispiace usare stringhe letterali:

 query.Include("Collection.Property")