EF LINQ include multiple and nested entities

Ok, mam trójpoziomowe byty o następującej hierarchii: kurs -> moduł - > Rozdział

Oto oryginalna deklaracja EF LINQ:

Course course = db.Courses
                .Include(i => i.Modules.Select(s => s.Chapters))
                .Single(x => x.Id == id); 
Teraz chcę dołączyć inną istotę o nazwie Lab, która jest powiązana z kursem.

Jak włączyć jednostkę laboratoryjną?

Próbowałem następujących, ale to nie działa:

Course course = db.Courses
                .Include(i => i.Modules.Select(s => s.Chapters) && i.Lab)
                .Single(x => x.Id == id); 
Jakieś pomysły na włączenie drugiej istoty? Każda rada lub informacja byłaby bardzo mile widziana. Dzięki!
Author: AnimaSola, 2013-04-02

5 answers

Czy próbowałeś dodać jeszcze jedną Include:

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

Twoje rozwiązanie nie powiedzie się, ponieważ Include nie przyjmuje operatora logicznego

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

Update Aby dowiedzieć się więcej, pobierz LinqPad i przejrzyj próbki. Myślę, że jest to najszybszy sposób na zapoznanie się z Linq i Lambda.

Na początek-różnica między Select a Include jest taka, że z Select decydujesz co? chcesz wrócić (aka projekcja). Include to chętne Ładowanie funkcja, która informuje Framework encji, że ma zawierać dane z innych tabel.

Składnia Include może być również w łańcuchu znaków. Tak:

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

Ale próbki w LinqPad wyjaśnia to lepiej.

 206
Author: Jens Kloster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-23 16:40:10

Include jest częścią interfejsu fluent interface, dzięki czemu można pisać wiele Include poleceń po sobie

 db.Courses.Include(i => i.Modules.Select(s => s.Chapters))
           .Include(i => i.Lab)
           .Single(x => x.Id == id); 
 21
Author: Ilya Ivanov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-02 12:55:59

Możesz również spróbować

db.Courses.Include("Modules.Chapters").Single(c => c.Id == id);
 16
Author: Martin Larsson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-05 11:13:50

W Entity Framework Core (EF.core) możesz użyć .ThenInclude do włączenia kolejnych poziomów.

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

Więcej informacji: https://docs.microsoft.com/en-us/ef/core/querying/related-data

Uwaga: Powiedz, że potrzebujesz wielokrotności ThenInclude() na blog.Posts, po prostu powtórz Include(blog => blog.Posts) i zrób kolejny 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
Author: Nick N.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-05 12:18:04

Można napisać metodę rozszerzenia w następujący sposób:

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

I używaj go w ten sposób nawet w ogólnej implementacji:

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

var query = context.Set<T>()
.Include(includedNavigationProperties);
 1
Author: Mohsen Afshin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-08 07:43:01