web-dev-qa-db-fra.com

Entity Framework - Inclure plusieurs niveaux de propriétés

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; }
}
320
Bob Horn

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);
623
Diego Torres

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)}")  
59
Judo

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();
44
thangcao

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 .

26
Lenny32

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 :)

18
dnxit

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.

11
Simon_Weaver

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")
3
mrmashal