Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Gieriges Laden
Mit der Include Methode können Sie verwandte Daten angeben, die in Abfrageergebnisse einbezogen werden sollen. Im folgenden Beispiel haben die Blogs, die in den Ergebnissen zurückgegeben werden, ihre Posts-Eigenschaft mit den zugehörigen Beiträgen gefüllt.
using (var context = new BloggingContext())
{
var blogs = await context.Blogs
.Include(blog => blog.Posts)
.ToListAsync();
}
Tipp
Entity Framework Core passt Navigationseigenschaften automatisch für alle anderen Entitäten an, die zuvor in der Instanz des Kontexts geladen wurden. Selbst wenn Sie die Daten für eine Navigationseigenschaft nicht explizit einschließen, wird die Eigenschaft möglicherweise immer noch aufgefüllt, wenn einige oder alle zugehörigen Entitäten zuvor geladen wurden.
Sie können verwandte Daten aus mehreren Beziehungen in eine einzelne Abfrage einschließen.
using (var context = new BloggingContext())
{
var blogs = await context.Blogs
.Include(blog => blog.Posts)
.Include(blog => blog.Owner)
.ToListAsync();
}
Vorsicht
Das gierige Laden einer Sammlungsnavigation in einer einzelnen Abfrage kann zu Leistungsproblemen führen. Weitere Informationen finden Sie unter Einzelne und geteilte Abfragen.
Einschließen mehrerer Ebenen
Sie können mithilfe der ThenInclude Methode einen Drilldown durch Beziehungen durchführen, um mehrere Ebenen verwandter Daten einzuschließen. Im folgenden Beispiel werden alle Blogs, ihre zugehörigen Beiträge und der Autor jedes Beitrags geladen.
using (var context = new BloggingContext())
{
var blogs = await context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.ToListAsync();
}
Sie können mehrere Aufrufe von ThenInclude verketten, um weitere Ebenen verwandter Daten einzuschließen.
using (var context = new BloggingContext())
{
var blogs = await context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.ThenInclude(author => author.Photo)
.ToListAsync();
}
Sie können alle Aufrufe kombinieren, um verwandte Daten aus mehreren Ebenen und mehreren Wurzeln in derselben Abfrage einzuschließen.
using (var context = new BloggingContext())
{
var blogs = await context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.ThenInclude(author => author.Photo)
.Include(blog => blog.Owner)
.ThenInclude(owner => owner.Photo)
.ToListAsync();
}
Möglicherweise möchten Sie mehrere verwandte Entitäten für eine der entitäten einschließen, die einbezogen werden. Wenn Sie z. B. Blogs abfragen, schließen Sie Posts ein und möchten dann sowohl die Author als auch die Tags der Posts einbeziehen. Um beide einzuschließen, müssen Sie jeden einschließenden Pfad angeben, der am Stamm beginnt. Beispiel: Blog -> Posts -> Author und Blog -> Posts -> Tags. Es bedeutet nicht, dass Sie redundante Verknüpfungen erhalten. in den meisten Fällen kombiniert EF die Verknüpfungen beim Generieren von SQL.
using (var context = new BloggingContext())
{
var blogs = await context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.Include(blog => blog.Posts)
.ThenInclude(post => post.Tags)
.ToListAsync();
}
Tipp
Sie können auch mehrere Navigationen mit einer einzigen Include Methode laden. Dies ist für Navigationsketten möglich, die ausschließlich aus Verweisen bestehen, oder wenn sie mit einer einzelnen Sammlung enden.
using (var context = new BloggingContext())
{
var blogs = await context.Blogs
.Include(blog => blog.Owner.AuthoredPosts)
.ThenInclude(post => post.Blog.Owner.Photo)
.ToListAsync();
}
Gefilterte Einträge
Wenn Sie "Einschließen" zum Laden verwandter Daten anwenden, können Sie der enthaltenen Sammlungsnavigation bestimmte aufzählbare Vorgänge hinzufügen, die das Filtern und Sortieren der Ergebnisse ermöglichen.
Unterstützte Vorgänge sind: Where, , OrderBy, OrderByDescending, ThenByThenByDescending, , und SkipTake.
Solche Vorgänge sollten auf die Sammlungsnavigation in der Lambda-Funktion angewendet werden, die an die Include-Methode übergeben wird, wie im folgenden Beispiel gezeigt:
using (var context = new BloggingContext())
{
var filteredBlogs = await context.Blogs
.Include(
blog => blog.Posts
.Where(post => post.BlogId == 1)
.OrderByDescending(post => post.Title)
.Take(5))
.ToListAsync();
}
Jede enthaltene Navigation ermöglicht nur einen eindeutigen Satz von Filtervorgängen. In Fällen, in denen mehrere Include-Vorgänge für eine bestimmte Sammlungsnavigation angewendet werden (blog.Posts in den folgenden Beispielen), können Filtervorgänge nur für eine davon angegeben werden:
using (var context = new BloggingContext())
{
var filteredBlogs = await 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))
.ToListAsync();
}
Alternativ können identische Vorgänge für jede Navigation angewendet werden, die mehrmals enthalten ist:
using (var context = new BloggingContext())
{
var filteredBlogs = await 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))
.ToListAsync();
}
Vorsicht
Im Falle von Nachverfolgungsabfragen kann das Ergebnis der gefilterten Include-Funktion aufgrund von Navigationskorrekturen unerwartet sein. Alle relevanten Entitäten, die zuvor abgefragt wurden und in der Änderungsverfolgung gespeichert wurden, werden in den Ergebnissen der Gefilterten Include-Abfrage angezeigt, auch wenn sie die Anforderungen des Filters nicht erfüllen. Erwägen Sie die Verwendung von NoTracking Queries oder erstellen Sie den DbContext neu, wenn Sie "Filtered Include" in diesen Situationen verwenden.
Beispiel:
var orders = await context.Orders.Where(o => o.Id > 1000).ToListAsync();
// customer entities will have references to all orders where Id > 1000, rather than > 5000
var filtered = await context.Customers.Include(c => c.Orders.Where(o => o.Id > 5000)).ToListAsync();
Hinweis
Bei Nachverfolgungsabfragen wird die Navigation, auf die ein gefiltertes Include angewendet wurde, als geladen betrachtet. Dies bedeutet, dass EF Core nicht versuchen wird, seine Werte mit explizitem Laden oder Lazy Loading erneut zu laden, auch wenn einige Elemente noch fehlen könnten.
Einschließen von abgeleiteten Typen
Sie können verwandte Daten aus der Navigation einbeziehen, die nur für einen abgeleiteten Typ definiert sind, indem Sie Include und ThenInclude verwenden.
Aufgrund des folgenden Modells:
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; }
}
Der Inhalt der School Navigation aller Personen, die Studierende sind, kann auf vielfältige Weise effizient geladen werden:
Verwenden von Cast
context.People.Include(person => ((Student)person).School).ToList()Verwenden des
asOperatorscontext.People.Include(person => (person as Student).School).ToList()Verwenden Sie eine Überladung von
Includemit einem Parameter des Typsstringcontext.People.Include("School").ToList()
Modellkonfiguration für das automatische Einbinden von Navigationen
Sie können eine Navigation im Modell so konfigurieren, dass sie jedes Mal einbezogen wird, wenn die Entität mithilfe AutoInclude der Methode aus der Datenbank geladen wird. Es hat dieselbe Auswirkung wie die Angabe von Include in der Navigation in jeder Abfrage, bei der der Entitätstyp in den Ergebnissen zurückgegeben wird. Das folgende Beispiel zeigt, wie Sie eine Navigation so konfigurieren, dass sie automatisch eingeschlossen wird.
modelBuilder.Entity<Theme>().Navigation(e => e.ColorScheme).AutoInclude();
Nach der obigen Konfiguration wird durch das Ausführen einer Abfrage wie unten gezeigt die Navigation für alle Themen in den Ergebnissen geladen.
using (var context = new BloggingContext())
{
var themes = await context.Themes.ToListAsync();
}
Diese Konfiguration wird auf jede Entität angewendet, die im Ergebnis zurückgegeben wird, unabhängig davon, wie sie in den Ergebnissen angezeigt wurde. Dies bedeutet, dass, wenn eine Entität aufgrund der Nutzung einer Navigation, der Verwendung von Include anstelle eines anderen Entitätstyps oder einer automatischen Inklusionskonfiguration im Ergebnis enthalten ist, alle automatisch einbezogenen Navigationen für sie geladen werden. Die gleiche Regel erstreckt sich auf die Navigationen, die bei abgeleiteten Entitätstypen automatisch enthalten sind.
Wenn Sie bei einer bestimmten Abfrage die zugehörigen Daten, die auf Modellebene so konfiguriert sind, dass sie automatisch einbezogen werden, nicht über eine Navigation laden möchten, können Sie die Methode IgnoreAutoIncludes in Ihrer Abfrage verwenden. Die Verwendung dieser Methode stoppt das Laden aller Navigationen, die der Benutzer als automatisch einbezogen konfiguriert hat. Wenn Sie eine Abfrage wie unten ausführen, werden alle Themen aus der Datenbank zurückgegeben, aber ColorScheme wird nicht geladen, obwohl es als automatisch eingeschlossene Navigation konfiguriert ist.
using (var context = new BloggingContext())
{
var themes = await context.Themes.IgnoreAutoIncludes().ToListAsync();
}
Hinweis
Navigationen zu besessenen Typen werden auch nach Konvention als automatisch einbezogen konfiguriert, und die Verwendung der IgnoreAutoIncludes-API verhindert nicht, dass sie eingeschlossen werden. Sie werden weiterhin in Abfrageergebnisse einbezogen.