it-swarm.com.de

EF LINQ enthält mehrere und verschachtelte Entitäten

Ok, ich habe dreistufige Entitäten mit der folgenden Hierarchie: Kurs -> Modul -> Kapitel

Hier war die ursprüngliche EF LINQ-Anweisung:

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

Jetzt möchte ich eine weitere Entität mit dem Namen Lab aufnehmen, die einem Kurs zugeordnet ist.

Wie binde ich die Lab-Entität ein?

Ich habe Folgendes versucht, aber es hat nicht funktioniert:

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

Irgendwelche Ideen zum Einbeziehen der 2. Einheit?

Jede Beratung oder Information wäre sehr dankbar. Vielen Dank!

144
AnimaSola

Haben Sie versucht, nur ein weiteres Include hinzuzufügen:

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

Ihre Lösung schlägt fehl, weil Include keinen booleschen Operator akzeptiert

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

Update Um mehr zu erfahren, laden Sie LinqPad herunter und schauen Sie sich die Beispiele an. Ich denke, es ist der schnellste Weg, sich mit Linq und Lambda vertraut zu machen.

Zunächst einmal - der Unterschied zwischen Select und Include besteht darin, dass Sie mit einem Select entscheiden was Sie möchten zurückkehren (aka Projektion). Das Include ist eine Eager Loading Funktion, die Entity Framework mitteilt, dass Daten aus anderen Tabellen eingeschlossen werden sollen.

Die Include-Syntax kann auch eine Zeichenfolge sein. So was:

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

Aber die Beispiele in LinqPad erklären dies besser.

219
Jens Kloster

Include ist Teil der fließenden Benutzeroberfläche, sodass Sie mehrere Include Anweisungen hintereinander schreiben können

 db.Courses.Include(i => i.Modules.Select(s => s.Chapters))
           .Include(i => i.Lab)
           .Single(x => x.Id == id); 
22
Ilya Ivanov

In Entity Framework Core (EF.core) Können Sie mit .ThenInclude Die nächsten Ebenen einbinden.

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

Weitere Informationen: https://docs.Microsoft.com/en-us/ef/core/querying/related-data

Hinweis: Angenommen, Sie benötigen mehrere ThenInclude() für blog.Posts, Wiederholen Sie einfach die Include(blog => blog.Posts) und mache ein anderes 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();
19
Nick N.

Sie können es auch versuchen

db.Courses.Include("Modules.Chapters").Single(c => c.Id == id);
17
Martin Larsson

Man kann eine Erweiterungsmethode wie diese schreiben:

    /// <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;
    }

Und verwenden Sie es auch in einer generischen Implementierung so:

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

var query = context.Set<T>()
.Include(includedNavigationProperties);
1
Mohsen Afshin