2012-05-30 12 views
221

Metoda Include() działa całkiem dobrze w przypadku list obiektów. Ale co, jeśli muszę przejść dwa poziomy głębokości? Na przykład poniższa metoda spowoduje zwrócenie ApplicationServers z pokazanymi tutaj właściwościami. Jednak ApplicationsWithOverrideGroup to inny kontener zawierający inne złożone obiekty. Czy mogę wykonać również funkcję Include() dla tej właściwości? Lub jak mogę załadować tę właściwość do pełnego załadowania?Struktura obiektu - zawiera wiele poziomów właściwości

Jak to stoi teraz ta metoda:

public IEnumerable<ApplicationServer> GetAll() 
{ 
    return this.Database.ApplicationServers 
     .Include(x => x.ApplicationsWithOverrideGroup)     
     .Include(x => x.ApplicationWithGroupToForceInstallList) 
     .Include(x => x.CustomVariableGroups)     
     .ToList(); 
} 

propaguje tylko właściwość enabled (poniżej), a nie aplikacji lub właściwości CustomVariableGroup (poniżej). Jak mogę to zrobić?

public class ApplicationWithOverrideVariableGroup : EntityBase 
{ 
    public bool Enabled { get; set; } 
    public Application Application { get; set; } 
    public CustomVariableGroup CustomVariableGroup { get; set; } 
} 
+0

Witam, Dlaczego otrzymuję wyjątek "Wyrażenie musi być wyrażeniem członka", gdy próbuję tego: Aby dołączyć kolekcję, a następnie kolekcję o jeden poziom niżej: 'query.Include (e => e.Level1Collection.Select (l1) => l1.Level2Collection)) '. –

+1

@BobHorn, Mam ten sam problem .. W moim przypadku zagnieżdżenie przechodzi w głąb wielu warstw, udało mi się zrobić to, co wskazałeś. W wygenerowanym SQL, mogłem zobaczyć, że wszystkie kolumny wracają z różnymi nazwami aliasów jak c1, c2 coś takiego. Moje pytanie brzmi: w jaki sposób mogę utworzyć zagnieżdżoną kolekcję DTO spośród wszystkich moich obejmuje :(.. Być może możesz wziąć powyższy przykład sam, ponieważ zwracamy wszystkie kolumny bez niestandardowego DTO (który sam jest zbiorem DTO's) – TechQuery

Odpowiedz

418

Dla EF 6

using System.Data.Entity; 

query.Include(x => x.Collection.Select(y => y.Property)) 

Zobacz Remarks po więcej przykładów.

Pamiętaj, aby dodać using System.Data.Entity;, aby uzyskać wersję Include, która przyjmuje lambdę.


Jeśli używasz EF rdzeń może skorzystać z nowej metody ThenInclude

query.Include(x => x.Collection) 
    .ThenInclude(x => x.Property); 
+1

Nie mogę wykonać funkcji Include() w ApplicationsWithOverrideGroup. Nie pojawia się w intellisense. –

+0

Nie mogę użyć twojej edycji, ponieważ ApplicationsWithOverrideGroup jest listą. Aplikacja jest właściwością dla każdego elementu na liście, a nie na samej liście. –

+1

Ahhhh, ale podany link wydaje się zapewniać odpowiedź. Pozwól mi spróbować: Aby dołączyć kolekcję, a następnie kolekcję o jeden poziom niżej: query.Include (e => e.Level1Collection.Select (l1 => l1.Level2Collection)). –

43

Jeśli dobrze cię rozumiem, pytasz o włączenie zagnieżdżonych właściwości. Jeśli tak, to:

.Include(x => x.ApplicationsWithOverrideGroup.NestedProp) 

lub

.Include("ApplicationsWithOverrideGroup.NestedProp") 

lub

.Include($"{nameof(ApplicationsWithOverrideGroup)}.{nameof(NestedProp)}") 
+4

Dzięki, mogę spróbować.Miałem nadzieję, że będzie w stanie zachować rzeczy mocno wpisane i unikać literałów ciągowych.Ale jeśli tak trzeba to zrobić ... –

+0

Jesteś blisko.Może nie być jasne, że ApplicationsWithOverrideGroup Dziękuję za pomoc! –

+0

@Judo, mam ten sam problem .. W moim przypadku zagnieżdżenie przechodzi w głąb wielu warstw, udało mi się zrobić to, co wskazałeś. W SQL, który został wygenerowany, mógłbym widzę, że wszystkie kolumny wracają z innym aliasem imię jak c1, c2 coś w tym stylu. Moje pytanie brzmi: w jaki sposób mogę utworzyć zagnieżdżoną kolekcję DTO spośród wszystkich moich obejmuje :(Może być, możesz wziąć powyższy przykład sam, w tym zwracamy wszystkie kolumny w Bez żadnego niestandardowego DTO (który sam jest zbiorem DTO) – TechQuery

24

Używanie "ThenInclude" załadować mutiple poziomy: Na przykład:

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

Wygląda na to, że jest to EF Core tylko –

+6

FYI: VS2017 system intellisense nie działał dla .ThereInclude. Po prostu wpisz to, jak powinno być, a podświetlanie powinno zniknąć. – JohnWrensby

+0

Chcę podkreślić komentarz @JohnWrensby, IntelliSense może czasami zajmować szczególnie dużo czasu w tych ThenInclude, może to być dość mylące dla nowych użytkowników. Miałem też przypadki, w których proste wyrażenie "Uwzględnij lambda" nie było obsługiwane poprawnie, dopóki po prostu nie wpiszesz go i skompilujesz, ignorując "błędy" pokazane w VS. – Pac0

13

Zrobiłem mały pomocnik dla Entity Framework 6 (.NET Core style), aby w łatwy sposób włączyć pod-jednostki.

Jest na Nuget teraz: 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(); 
8

Miałem również korzystać z wielu obejmuje i na 3. poziomie potrzebowałem wiele właściwości

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

może komuś pomóc:)

+0

można to zrobić bez powtarzania '.Include (x => x.Shifts.Selekt (r => r.Rate). Wybierz (rt => rt ......' – Multinerd

+0

cóż to zależy, jak głęboko chcesz go – dnxit

3

Więcej EFCore examples on MSDN pokazuje, że można wykonać pewne skomplikowane czynności za pomocą Include i ThenInclude.

To jest dobry przykład tego, jak skomplikowany możesz uzyskać (to wszystko jedno zdanie!):

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

Zobacz jak można łańcuch Include nawet po ThenInclude i to niby „resetuje” z powrotem do poziomu podmiotu poziomu górnego (Instruktorów).

Możesz nawet powtórzyć tę samą kolekcję "pierwszego poziomu" (CourseAssignments) wiele razy, a następnie osobne polecenia ThenIncludes, aby dostać się do różnych obiektów podrzędnych.

Uwaga faktyczne zapytanie należy oznaczyć na końcu łańcucha Include lub ThenIncludes. Następujące nie działa:

gorąco polecam skonfigurować rejestrowanie i upewnić się, że pytania nie są poza kontrolą, jeśli jesteś w tym więcej niż jedną lub dwie rzeczy. Ważne jest, aby zobaczyć, jak to działa, a zauważysz, że każde oddzielne "uwzględnienie" jest zwykle nową kwerendą, aby uniknąć masowych połączeń zwracających nadmiarowe dane.

AsNoTracking może znacznie przyspieszyć działanie, jeśli nie zamierzasz edytować elementów i odzyskiwać.

+0

Czy istnieje sposób na uzyskanie zarówno rejestracji, jak i departamentów bez powtórzenia. Zawiera kurs CourseAssignment i kurs? (Jak dotąd wygląda na to, że Api może wejść głębiej z. Then Include, lub wrócić do najwyższego poziomu dzięki .Include, ale nie ma nic do pozostania na tym samym poziomie?) –

+0

Jeśli chcesz leniwego ładowania, zostań dostrojony do EF Core 2.1 https://blogs.msdn.microsoft.com/dotnet/2018/02/02/entity-framework-core -2-1-roadmap/ale jeśli po prostu chcesz załadować więcej na tym samym poziomie, myślę, że jest to zgodne z projektem.Nie jestem pewien, co myślisz - nie wymaga wiele dodatkowych czynności i to bardzo redukuje to, co powraca z bazy danych. Jednostka może po prostu mieć jedną lub dwie rzeczy "tego samego poziomu", ale może również mieć 50 dla dużego projektu, ing explicit znacznie przyspiesza twoją aplikację. –

Powiązane problemy