2013-04-02 13 views
127

Ok, mam tri-wyrównane podmioty o następującej hierarchii: kurs -> Moduły -> RozdziałEF LINQ obejmować wiele i zagnieżdżonych podmioty

Tu był oryginalny rachunek EF LINQ:

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

teraz , Chcę dołączyć inny podmiot o nazwie Lab, który jest powiązany z kursem.

Jak dołączyć encję Lab?

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

pomysłów na tym 2nd Entity?

Wszelkie porady lub informacje są bardzo cenne. Dzięki!

+1

Dodanie kolejnego '.Include' powinno zadziałać, chyba że masz na myśli, że dodatkowy element to wnuk Course. [Zobacz tę] (http://stackoverflow.com/questions/3356541/entity-framework-linq-query-include-multiple-children-entities) lub [lepszą opcją jest to] (http://stackoverflow.com/ pytania/13819856/entity-framework-5-multiple-include-is-this-possible) –

Odpowiedz

196

Czy próbowali po prostu dodając kolejny 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 działa, ponieważ Include nie bierze logiczną operatora

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

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

Na początek - Różnica między Select i Include jest to, że z wybraną zdecydujesz co chcesz powrócić (aka projekcji). Funkcja Uwzględnij jest funkcją, która mówi Entity Framework, że chcesz dołączyć dane z innych tabel.

Składnia Include może być również w postaci ciągu. W ten sposób:

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

Ale próbki w LinqPad wyjaśniają to lepiej.

+0

Doceń to! Gdzie mogę dowiedzieć się więcej o tym? Szczególnie interesuje mnie różnica między Include a Select – AnimaSola

+1

@AnimaSola I zaktualizowałem moją odpowiedź –

+2

Tylko ta zadziałała dla mnie: '.Include (" Module.Hapter ")'. Jakiś pomysł, dlaczego tak się stało? –

20

Include jest częścią płynny interfejs, dzięki czemu można napisać wiele Include oświadczenia każdy po drugiej

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

docenić! czy możesz wskazać mi, gdzie mogę dowiedzieć się więcej o tym? Dzięki! – AnimaSola

+0

Czy wiesz, jaka jest składnia, jeśli moduły mają wiele tabel, do których chcesz dołączyć? Powiedz, że łączy się z rozdziałami i czymś jeszcze? –

+0

Czy płynnie wchodzi w .Net czy jest to biblioteka, którą należy zainstalować? – codea

15

Można także spróbować

db.Courses.Include("Modules.Chapters").Single(c => c.Id == id); 
+2

Dzięki - notacja kropkowa w łańcuchu bardzo przydatna – Evert

0

Ktoś może napisać metodę rozszerzenia tak:

/// <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żywać go tak, nawet w ogólnej implementacji entation:

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

var query = context.Set<T>() 
.Include(includedNavigationProperties); 
+0

Próbowałem twojej odpowiedzi, ale rzuca ona stackoverflowexceptions z powodu nieskończonej pętli z samym sobą. –

+1

@VictoriaS., Możesz zmienić nazwę metody rozszerzenia tak, aby nie kolidowała z prawdziwym 'Include' –

7

W Entity Framework rdzenia (EF.core) można użyć .ThenInclude za tym kolejne poziomy.

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: Powiedzieć trzeba wiele ThenInclude() na blog.Posts, tylko powtórzyć Include(blog => blog.Posts) i zrobić 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(); 
var blogs = context.Blogs 
    .Include(blog => blog.Posts) 
     .ThenInclude(post => post.Author) 
    .Include(blog => blog.Posts) 
     .ThenInclude(post => post.Other) 
.ToList(); 
+0

W EF.core wydaje mi się, że nie jestem w stanie zrobić .Include (i => i.Modules.Select (s) => s.Chapters)), konkretnie. Wybierz w środku .Include. Czy ktoś może potwierdzić lub mówić do? – ttugates

+0

@ttugates Co zamierzasz zrobić z tym wyborem? Myślę, że to, co chcesz zrobić, to dokładnie to, co robisz z 'ThenInclude' w rdzeniu EF. Być może zadaj pytanie na dobrym przykładzie, abyśmy mogli odpowiedzieć na to pytanie. –

+0

[@Nick N] (https://stackoverflow.com/users/869033/nick-n) - [Entity Framework Linq Query: How to Where na wielu właściwościach Nav i wybierz z 3rd Nav Property] (https: // stackoverflow .com/questions/47870578/entity-framework-linq-query-how-to-where-on-many-nav-properties-and-select). Ponieważ to, co wybieram, nie jest tym, na którym się właśnie dopasowuję, uwzględnienia nie są konieczne, więc pytanie jest styczne. Moje pytanie może być zbyt "wąskie", ale doceniam każdą pomoc. – ttugates

Powiązane problemy