EF LINQ inclut des entités multiples et imbriquées

Ok, j'ai des entités à trois niveaux avec la hiérarchie suivante: Course -> Module - > Chapter

Voici la déclaration EF LINQ originale:

Course course = db.Courses
                .Include(i => i.Modules.Select(s => s.Chapters))
                .Single(x => x.Id == id); 

Maintenant, je veux inclure une autre entité appelée Lab qui est associée à un cours.

Comment puis-je inclure L'entité Lab?

J'ai essayé ce qui suit, mais cela n'a pas fonctionné:

Course course = db.Courses
                .Include(i => i.Modules.Select(s => s.Chapters) && i.Lab)
                .Single(x => x.Id == id); 

Des idées sur l'inclusion de la 2ème entité?

Tout conseil ou information serait très apprécié. Merci!

130
demandé sur AnimaSola 2013-04-02 16:51:14

5 réponses

Avez-vous essayé d'ajouter un autre Include:

Course course = db.Courses
                .Include(i => i.Modules.Select(s => s.Chapters))
                .Include(i => i.Lab)
                .Single(x => x.Id == id);

Votre solution échoue car Include ne prend pas un opérateur booléen

Include(i => i.Modules.Select(s => s.Chapters) &&          i.Lab)
                           ^^^                  ^             ^ 
                          list           bool operator    other list

Mise à Jour Pour en savoir plus, téléchargez LinqPad et parcourez les exemples. Je pense que c'est le moyen le plus rapide de se familiariser avec Linq et Lambda.

Comme un début - la différence entre Select et Include est que cela avec un Select vous décidez quoi vous voulez revenir (aka projection). Le Inclure est un Chargement impatient fonction, qui indique Entity Framework que vous voulez qu'il inclue des données provenant d'autres tables.

La syntaxe Include peut également être en chaîne. Comme ceci:

           db.Courses
            .Include("Module.Chapter")
            .Include("Lab")
            .Single(x => x.Id == id);

Mais les échantillons de LinqPad expliquent mieux cela.

206
répondu Jens Kloster 2014-04-23 16:40:10

Include est une partie de l'interface fluide, de sorte que vous pouvez écrire plusieurs Include déclarations suivantes d'autres

 db.Courses.Include(i => i.Modules.Select(s => s.Chapters))
           .Include(i => i.Lab)
           .Single(x => x.Id == id); 
21
répondu Ilya Ivanov 2013-04-02 12:55:59

Vous pouvez également essayer

db.Courses.Include("Modules.Chapters").Single(c => c.Id == id);
16
répondu Martin Larsson 2015-05-05 11:13:50

Dans Entity Framework Core (EF.core), Vous pouvez utiliser .ThenInclude pour inclure les niveaux suivants.

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

Plus d'informations: https://docs.microsoft.com/en-us/ef/core/querying/related-data

Remarque: Dites que vous avez besoin de plusieurs ThenInclude() sur blog.Posts, répétez simplement le Include(blog => blog.Posts) et faites un autre ThenInclude(post => post.Other).

var blogs = context.Blogs
    .Include(blog => blog.Posts)
        .ThenInclude(post => post.Author)
    .Include(blog => blog.Posts)
        .ThenInclude(post => post.Other)
 .ToList();
11
répondu Nick N. 2018-03-05 12:18:04

On peut écrire une méthode d'extension comme ceci:

    /// <summary>
    /// Includes an array of navigation properties for the specified query 
    /// </summary>
    /// <typeparam name="T">The type of the entity</typeparam>
    /// <param name="query">The query to include navigation properties for that</param>
    /// <param name="navProperties">The array of navigation properties to include</param>
    /// <returns></returns>
    public static IQueryable<T> Include<T>(this IQueryable<T> query, params string[] navProperties)
        where T : class
    {
        foreach (var navProperty in navProperties)
            query = query.Include(navProperty);

        return query;
    }

Et l'utiliser comme ceci même dans une implémentation Générique:

string[] includedNavigationProperties = new string[] { "NavProp1.SubNavProp", "NavProp2" };

var query = context.Set<T>()
.Include(includedNavigationProperties);
1
répondu Mohsen Afshin 2016-08-08 07:43:01