Chętne ładowanie powiązanych danych
Wczesne ładowanie
Możesz użyć Include
metody , aby określić powiązane dane, które mają zostać uwzględnione w wynikach zapytania. W poniższym przykładzie blogi zwrócone w wynikach będą miały swoją Posts
właściwość wypełniona powiązanymi wpisami.
using (var context = new BloggingContext())
{
var blogs = context.Blogs
.Include(blog => blog.Posts)
.ToList();
}
Napiwek
Program Entity Framework Core automatycznie naprawi właściwości nawigacji do innych jednostek, które zostały wcześniej załadowane do wystąpienia kontekstu. Nawet jeśli nie dołączysz jawnie danych do właściwości nawigacji, właściwość może być nadal wypełniana, jeśli niektóre lub wszystkie powiązane jednostki zostały wcześniej załadowane.
W jednym zapytaniu można uwzględnić powiązane dane z wielu relacji.
using (var context = new BloggingContext())
{
var blogs = context.Blogs
.Include(blog => blog.Posts)
.Include(blog => blog.Owner)
.ToList();
}
Uwaga
Chętne ładowanie nawigacji kolekcji w jednym zapytaniu może powodować problemy z wydajnością. Aby uzyskać więcej informacji, zobacz Pojedyncze i podzielone zapytania.
Uwzględnianie wielu poziomów
Możesz przejść do szczegółów relacji, aby uwzględnić wiele poziomów powiązanych danych przy użyciu ThenInclude
metody . W poniższym przykładzie ładuje się wszystkie blogi, powiązane wpisy i autor każdego wpisu.
using (var context = new BloggingContext())
{
var blogs = context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.ToList();
}
Możesz połączyć wiele wywołań, aby ThenInclude
kontynuować, w tym dalsze poziomy powiązanych danych.
using (var context = new BloggingContext())
{
var blogs = context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.ThenInclude(author => author.Photo)
.ToList();
}
Wszystkie wywołania można połączyć w celu uwzględnienia powiązanych danych z wielu poziomów i wielu katalogów głównych w tym samym zapytaniu.
using (var context = new BloggingContext())
{
var blogs = context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.ThenInclude(author => author.Photo)
.Include(blog => blog.Owner)
.ThenInclude(owner => owner.Photo)
.ToList();
}
Możesz uwzględnić wiele powiązanych jednostek dla jednej z uwzględnionych jednostek. Na przykład podczas wykonywania zapytań Blogs
uwzględnij Posts
element , a następnie chcesz uwzględnić zarówno element , jak Author
i Tags
.Posts
Aby uwzględnić oba te elementy, należy określić każdą ścieżkę dołączania rozpoczynającą się od katalogu głównego. Na przykład Blog -> Posts -> Author
i Blog -> Posts -> Tags
. Nie oznacza to, że uzyskasz nadmiarowe sprzężenia; w większości przypadków program EF połączy sprzężenia podczas generowania kodu SQL.
using (var context = new BloggingContext())
{
var blogs = context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.Include(blog => blog.Posts)
.ThenInclude(post => post.Tags)
.ToList();
}
Napiwek
Można również załadować wiele nawigacji przy użyciu jednej Include
metody. Jest to możliwe w przypadku nawigacji "łańcuchów", które są odwołaniami lub gdy kończą się pojedynczą kolekcją.
using (var context = new BloggingContext())
{
var blogs = context.Blogs
.Include(blog => blog.Owner.AuthoredPosts)
.ThenInclude(post => post.Blog.Owner.Photo)
.ToList();
}
Filtrowane dołączanie
Podczas stosowania funkcji Uwzględnij do ładowania powiązanych danych można dodać pewne operacje wyliczalne do dołączonej nawigacji kolekcji, co umożliwia filtrowanie i sortowanie wyników.
Obsługiwane operacje to: Where
, , OrderBy
, OrderByDescending
ThenBy
, ThenByDescending
, Skip
, i Take
.
Takie operacje należy zastosować w nawigacji kolekcji w metodzie lambda przekazanej do metody Include, jak pokazano w poniższym przykładzie:
using (var context = new BloggingContext())
{
var filteredBlogs = context.Blogs
.Include(
blog => blog.Posts
.Where(post => post.BlogId == 1)
.OrderByDescending(post => post.Title)
.Take(5))
.ToList();
}
Każda dołączona nawigacja umożliwia tylko jeden unikatowy zestaw operacji filtrowania. W przypadkach, gdy dla danej nawigacji kolekcji zastosowano wiele operacji dołączania (blog.Posts
w poniższych przykładach), operacje filtrowania można określić tylko na jednym z nich:
using (var context = new BloggingContext())
{
var filteredBlogs = context.Blogs
.Include(blog => blog.Posts.Where(post => post.BlogId == 1))
.ThenInclude(post => post.Author)
.Include(blog => blog.Posts)
.ThenInclude(post => post.Tags.OrderBy(postTag => postTag.TagId).Skip(3))
.ToList();
}
Zamiast tego można zastosować identyczne operacje dla każdej nawigacji, która jest uwzględniana wiele razy:
using (var context = new BloggingContext())
{
var filteredBlogs = context.Blogs
.Include(blog => blog.Posts.Where(post => post.BlogId == 1))
.ThenInclude(post => post.Author)
.Include(blog => blog.Posts.Where(post => post.BlogId == 1))
.ThenInclude(post => post.Tags.OrderBy(postTag => postTag.TagId).Skip(3))
.ToList();
}
Uwaga
W przypadku zapytań śledzenia wyniki filtrowanego dołączania mogą być nieoczekiwane z powodu naprawy nawigacji. Wszystkie odpowiednie jednostki, których dotyczy zapytanie dotyczące poprzednio i zostały zapisane w monitorze zmian, będą obecne w wynikach zapytania Filtrowane uwzględnij, nawet jeśli nie spełniają wymagań filtru. Rozważ użycie NoTracking
zapytań lub ponowne utworzenie elementu DbContext podczas korzystania z filtrowanego dołączania w tych sytuacjach.
Przykład:
var orders = context.Orders.Where(o => o.Id > 1000).ToList();
// customer entities will have references to all orders where Id > 1000, rather than > 5000
var filtered = context.Customers.Include(c => c.Orders.Where(o => o.Id > 5000)).ToList();
Uwaga
W przypadku zapytań śledzenia nawigacja, na której zastosowano filtrowane dołączanie, jest uważana za załadowaną. Oznacza to, że program EF Core nie będzie próbował ponownie załadować swoich wartości przy użyciu jawnego ładowania lub ładowania leniwego, mimo że niektóre elementy nadal mogą brakować.
Dołączanie do typów pochodnych
Powiązane dane można uwzględnić na podstawie nawigacji zdefiniowanej tylko dla typu pochodnego przy użyciu metod Include
i ThenInclude
.
Biorąc pod uwagę następujący model:
public class SchoolContext : DbContext
{
public DbSet<Person> People { get; set; }
public DbSet<School> Schools { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<School>().HasMany(s => s.Students).WithOne(s => s.School);
}
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Student : Person
{
public School School { get; set; }
}
public class School
{
public int Id { get; set; }
public string Name { get; set; }
public List<Student> Students { get; set; }
}
School
Zawartość nawigacji wszystkich Osoby, które są uczniami, mogą być chętnie ładowane przy użyciu wielu wzorców:
Korzystanie z rzutów
context.People.Include(person => ((Student)person).School).ToList()
Korzystanie z
as
operatoracontext.People.Include(person => (person as Student).School).ToList()
Użycie przeciążenia tego parametru
Include
przyjmuje parametr typustring
context.People.Include("School").ToList()
Konfiguracja modelu na potrzeby automatycznego dołączania nawigacji
Nawigację w modelu można skonfigurować tak, aby została uwzględniona za każdym razem, gdy jednostka jest ładowana z bazy danych przy użyciu AutoInclude
metody . Ma taki sam efekt jak określenie Include
z nawigacją w każdym zapytaniu, w którym typ jednostki jest zwracany w wynikach. W poniższym przykładzie pokazano, jak skonfigurować nawigację do automatycznego dołączania.
modelBuilder.Entity<Theme>().Navigation(e => e.ColorScheme).AutoInclude();
Po powyższej konfiguracji uruchomienie zapytania, jak pokazano poniżej, spowoduje załadowanie ColorScheme
nawigacji dla wszystkich motywów w wynikach.
using (var context = new BloggingContext())
{
var themes = context.Themes.ToList();
}
Ta konfiguracja jest stosowana dla każdej jednostki zwróconej w wyniku niezależnie od tego, jak została wyświetlona w wynikach. Oznacza to, że jeśli jednostka jest w wyniku korzystania z nawigacji, używając Include
innego typu jednostki lub konfiguracji automatycznego dołączania, załaduje wszystkie automatycznie dołączone nawigacje. Ta sama reguła jest rozszerzana na nawigacje skonfigurowane jako automatycznie dołączone do typu pochodnego jednostki.
Jeśli dla określonego zapytania nie chcesz ładować powiązanych danych za pośrednictwem nawigacji, która jest skonfigurowana na poziomie modelu do automatycznego dołączania, możesz użyć IgnoreAutoIncludes
metody w zapytaniu. Użycie tej metody spowoduje zatrzymanie ładowania wszystkich nawigacji skonfigurowanych jako automatyczne dołączanie przez użytkownika. Uruchomienie zapytania, takiego jak poniżej, spowoduje przywrócenie wszystkich motywów z bazy danych, ale nie zostanie załadowane ColorScheme
, mimo że jest skonfigurowane jako nawigacja dołączana automatycznie.
using (var context = new BloggingContext())
{
var themes = context.Themes.IgnoreAutoIncludes().ToList();
}
Uwaga
Nawigacje do typów należących są również konfigurowane jako dołączane automatycznie zgodnie z konwencją i używanie IgnoreAutoIncludes
interfejsu API nie uniemożliwia dołączania ich. Będą one nadal uwzględniane w wynikach zapytania.