La méthode Include () fonctionne assez bien pour les listes sur les objets. Mais que se passe-t-il si je dois aller à deux niveaux de profondeur? Par exemple, la méthode ci-dessous renvoie les serveurs d'applications avec les propriétés incluses présentées ici. Cependant, ApplicationsWithOverrideGroup est un autre conteneur qui contient d'autres objets complexes. Puis-je faire un Include () sur cette propriété aussi? Ou comment puis-je obtenir cette propriété à charger complètement?
En l’état actuel, cette méthode:
public IEnumerable<ApplicationServer> GetAll()
{
return this.Database.ApplicationServers
.Include(x => x.ApplicationsWithOverrideGroup)
.Include(x => x.ApplicationWithGroupToForceInstallList)
.Include(x => x.CustomVariableGroups)
.ToList();
}
Ne peuplera que la propriété Enabled (ci-dessous) et non les propriétés Application ou CustomVariableGroup (ci-dessous). Comment puis-je y arriver?
public class ApplicationWithOverrideVariableGroup : EntityBase
{
public bool Enabled { get; set; }
public Application Application { get; set; }
public CustomVariableGroup CustomVariableGroup { get; set; }
}
Pour EF 6
using System.Data.Entity;
query.Include(x => x.Collection.Select(y => y.Property))
Voir Remarques pour plus d'exemples.
Assurez-vous d’ajouter using System.Data.Entity;
pour obtenir la version de Include
qui prend un lambda.
Pour EF Core
Utilisez la nouvelle méthode ThenInclude
query.Include(x => x.Collection)
.ThenInclude(x => x.Property);
Si je vous ai bien compris, vous parlez de l'inclusion de propriétés imbriquées. Si c'est le cas :
.Include(x => x.ApplicationsWithOverrideGroup.NestedProp)
ou
.Include("ApplicationsWithOverrideGroup.NestedProp")
ou
.Include($"{nameof(ApplicationsWithOverrideGroup)}.{nameof(NestedProp)}")
EF Core: Utilisation de "Then Include" pour charger plusieurs niveaux: Par exemple:
var blogs = context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.ThenInclude(author => author.Photo)
.ToList();
J'ai créé un petit assistant pour Entity Framework 6 (style .Net Core), pour inclure les sous-entités à la manière de Nice.
C'est sur NuGet maintenant: 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();
Le paquet est disponible sur GitHub .
Je devais également utiliser plusieurs inclus et au 3ème niveau j'avais besoin de plusieurs propriétés
(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();
Cela peut aider quelqu'un :)
Plus Les exemples EFCore sur MSDN montrent que vous pouvez faire des choses assez complexes avec Include
et ThenInclude
.
C’est un bon exemple de la complexité que vous pouvez obtenir (c’est une affirmation!):
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();
Voyez comment vous pouvez chaîner Include
même après ThenInclude
et que cela vous réinitialise en quelque sorte au niveau de l'entité de niveau supérieur (instructeurs).
Vous pouvez même répéter plusieurs fois la même collection de 'premier niveau' (CourseAssignments) suivie de commandes distinctes ThenIncludes
pour accéder à différentes entités enfant.
Notez que votre requête doit être étiquetée à la fin de la chaîne Include
ou ThenIncludes
. Ce qui suit ne fonctionne pas:
var query = _context.Instructors.AsQueryable();
query.Include(i => i.OfficeAssignment);
var first10Instructors = query.Take(10).ToArray();
Je vous recommande fortement de configurer la journalisation et de vous assurer que vos requêtes ne sont pas hors de contrôle si vous incluez plus d'une ou deux choses. Il est important de voir comment cela fonctionne réellement - et vous remarquerez que chaque "inclusion" distincte est généralement une nouvelle requête afin d'éviter que des jointures massives renvoient des données redondantes.
AsNoTracking
peut considérablement accélérer les choses si vous n'avez pas l'intention de modifier les entités et de les enregistrer à nouveau.
Permettez-moi de préciser que vous pouvez utiliser la surcharge de chaînes pour inclure des niveaux imbriqués quelles que soient les multiplicités des relations correspondantes, si vous voulez bien utiliser des littéraux de chaîne:
query.Include("Collection.Property")