Laden von verknüpften DatenLoading Related Data

Entity Framework Core können Sie die Navigationseigenschaften zum Laden verknüpfter Entitäten im Modell zu verwenden.Entity Framework Core allows you to use the navigation properties in your model to load related entities. Es gibt drei allgemeine O/RM-Muster, die zum Laden von verknüpften Daten verwendet.There are three common O/RM patterns used to load related data.

  • Unverzüglichem Laden bedeutet, dass die verknüpften Daten aus der Datenbank als Teil der ursprünglichen Abfrage geladen werden.Eager loading means that the related data is loaded from the database as part of the initial query.
  • Explizites Laden bedeutet, dass die verwandten Daten explizit aus der Datenbank zu einem späteren Zeitpunkt geladen werden.Explicit loading means that the related data is explicitly loaded from the database at a later time.
  • Verzögertes Laden bedeutet, dass die verwandten Daten transparent aus der Datenbank geladen werden, wenn die Navigationseigenschaft zugegriffen wird.Lazy loading means that the related data is transparently loaded from the database when the navigation property is accessed. Verzögertes Laden ist noch nicht mit EF Core möglich.Lazy loading is not yet possible with EF Core.

Tipp

Sie können anzeigen, dass dieser Artikel Beispiel auf GitHub.You can view this article's sample on GitHub.

Eager LoadingEager loading

Sie können die Include Methode, um verwandte Daten angeben, die in den Ergebnissen enthalten sein.You can use the Include method to specify related data to be included in query results. Im folgenden Beispiel müssen die Blogs, die in den Ergebnissen zurückgegeben werden ihre Posts Eigenschaft, die mit den zugehörigen Beiträgen aufgefüllt.In the following example, the blogs that are returned in the results will have their Posts property populated with the related posts.

using (var context = new BloggingContext())
{
    var blogs = context.Blogs
        .Include(blog => blog.Posts)
        .ToList();
}

Tipp

Entity Framework Core wird automatisch ein Fixup-Navigationseigenschaften für alle anderen Entitäten, die zuvor in die Kontextinstanz geladen wurden.Entity Framework Core will automatically fix-up navigation properties to any other entities that were previously loaded into the context instance. Damit auch, wenn Sie die Daten für eine Navigationseigenschaft explizit nicht einschließen, die Eigenschaft kann noch immer aufgefüllt werden, wenn einige oder alle verknüpften Entitäten wurden zuvor geladen.So even if you don't explicitly include the data for a navigation property, the property may still be populated if some or all of the related entities were previously loaded.

Sie können aufeinander bezogene Daten in mehreren Beziehungen in einer einzelnen Abfrage einschließen.You can include related data from multiple relationships in a single query.

using (var context = new BloggingContext())
{
    var blogs = context.Blogs
        .Include(blog => blog.Posts)
        .Include(blog => blog.Owner)
        .ToList();
}

Einschließlich mehrere EbenenIncluding multiple levels

Drilldown kann über Beziehungen zu mehrere Stufen der verknüpften Daten mithilfe der ThenInclude Methode.You can drill down thru relationships to include multiple levels of related data using the ThenInclude method. Im folgende Beispiel lädt alle Blogs, Verwandte Beiträge und der Autor jedes Post.The following example loads all blogs, their related posts, and the author of each post.

using (var context = new BloggingContext())
{
    var blogs = context.Blogs
        .Include(blog => blog.Posts)
            .ThenInclude(post => post.Author)
        .ToList();
}

Sie können mehrere Aufrufe verkettet ThenInclude zu fortfahren, einschließlich der weiteren Ebenen verknüpfter Daten.You can chain multiple calls to ThenInclude to continue including further levels of related data.

using (var context = new BloggingContext())
{
    var blogs = context.Blogs
        .Include(blog => blog.Posts)
            .ThenInclude(post => post.Author)
                .ThenInclude(author => author.Photo)
        .ToList();
}

Sie können diese Option, um verwandte Daten aus mehreren Ebenen und mehrere Stämme in derselben Abfrage umfassen alle kombinieren.You can combine all of this to include related data from multiple levels and multiple roots in the same query.

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

Möglicherweise sollen mehrere verknüpfte Entitäten für eine der Entitäten, die gerade enthalten ist.You may want to include multiple related entities for one of the entities that is being included. Beispielsweise beim Abfragen von Bloge, Sie enthalten Posts , und klicken Sie dann beide einschließen möchten die Author und Tags von der Posts.For example, when querying Blogs, you include Posts and then want to include both the Author and Tags of the Posts. Zu diesem Zweck müssen Sie angeben, angefangen beim Stamm Pfad enthalten.To do this, you need to specify each include path starting at the root. Beispielsweise Blog -> Posts -> Author und Blog -> Posts -> Tags.For example, Blog -> Posts -> Author and Blog -> Posts -> Tags. Dies bedeutet nicht, dass erhalten Sie redundante Joins, in den meisten Fällen, die EF zu konsolidieren, werden, die Joins beim Generieren von SQL.This does not mean you will get redundant joins, in most cases EF will consolidate the joins when generating 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();
}

Ignoriert enthältIgnored includes

Wenn Sie die Abfrage ändern, sodass sie nicht mehr Instanzen des Entitätstyps, die zurückgibt mit der Abfrage wurde gestartet, werden die Operatoren Include ignoriert.If you change the query so that it no longer returns instances of the entity type that the query began with, then the include operators are ignored.

Im folgenden Beispiel werden die Include-Operatoren basierend auf den Blog, aber dann die Select Operator wird verwendet, so ändern Sie die Abfrage aus, um einen anonymen Typ zurückgegeben.In the following example, the include operators are based on the Blog, but then the Select operator is used to change the query to return an anonymous type. Die Include-Operatoren haben in diesem Fall keine Auswirkungen.In this case, the include operators have no effect.

using (var context = new BloggingContext())
{
    var blogs = context.Blogs
        .Include(blog => blog.Posts)
        .Select(blog => new
        {
            Id = blog.BlogId,
            Url = blog.Url
        })
        .ToList();
}

EF Core protokolliert standardmäßig eine Warnung bei enthalten Operatoren werden ignoriert.By default, EF Core will log a warning when include operators are ignored. Finden Sie unter Protokollierung für Weitere Informationen zur Anzeige von Protokollausgaben.See Logging for more information on viewing logging output. Sie können das Verhalten ändern, wenn ein Operator Include ignoriert wird, entweder auslösen oder Unternehmen Sie nichts.You can change the behavior when an include operator is ignored to either throw or do nothing. Dies erfolgt, wenn Sie die Optionen für den Kontext - in der Regel in einrichten DbContext.OnConfiguring, oder im Startup.cs bei Verwendung von ASP.NET Core.This is done when setting up the options for your context - typically in DbContext.OnConfiguring, or in Startup.cs if you are using ASP.NET Core.

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder
        .UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=EFQuerying;Trusted_Connection=True;ConnectRetryCount=0")
        .ConfigureWarnings(warnings => warnings.Throw(CoreEventId.IncludeIgnoredWarning));
}

Explizites LadenExplicit loading

Hinweis

Diese Funktion wurde in der EF Core 1.1 eingeführt.This feature was introduced in EF Core 1.1.

Sie können explizit laden, eine Navigationseigenschaft über die DbContext.Entry(...) API.You can explicitly load a navigation property via the DbContext.Entry(...) API.

using (var context = new BloggingContext())
{
    var blog = context.Blogs
        .Single(b => b.BlogId == 1);

    context.Entry(blog)
        .Collection(b => b.Posts)
        .Load();

    context.Entry(blog)
        .Reference(b => b.Owner)
        .Load();
}

Sie können auch explizit eine Navigationseigenschaft laden, durch Ausführen einer separaten Abfrage, die die verknüpften Entitäten zurückgibt.You can also explicitly load a navigation property by executing a seperate query that returns the related entities. Wenn die änderungsnachverfolgung aktiviert ist, beim Laden einer Entität EF Core automatisch legen Sie die Navigationseigenschaften der neu geladenen workflowprozessinstanz zum Verweisen auf alle Entitäten, die bereits geladen, und legen Sie die Navigationseigenschaften der bereits geladene Entitäten zum Verweisen auf die Entität neu geladen.If change tracking is enabled, then when loading an entity, EF Core will automatically set the navigation properties of the newly-loaded entitiy to refer to any entities already loaded, and set the navigation properties of the already-loaded entities to refer to the newly-loaded entity.

Außerdem erhalten Sie eine LINQ-Abfrage, die den Inhalt einer Navigationseigenschaft darstellt.You can also get a LINQ query that represents the contents of a navigation property.

Dadurch können Sie Aktionen wie die aggregate-Operator über die verknüpften Entitäten ausführen, ohne sie in den Arbeitsspeicher laden ausgeführt werden.This allows you to do things such as running an aggregate operator over the related entities without loading them into memory.

using (var context = new BloggingContext())
{
    var blog = context.Blogs
        .Single(b => b.BlogId == 1);

    var postCount = context.Entry(blog)
        .Collection(b => b.Posts)
        .Query()
        .Count();
}

Sie können auch filtern, welche verknüpften Entitäten in den Arbeitsspeicher geladen werden.You can also filter which related entities are loaded into memory.

using (var context = new BloggingContext())
{
    var blog = context.Blogs
        .Single(b => b.BlogId == 1);

    var goodPosts = context.Entry(blog)
        .Collection(b => b.Posts)
        .Query()
        .Where(p => p.Rating > 3)
        .ToList();
}

Lazy LoadingLazy loading

Verzögertes Laden wird noch von EF Core nicht unterstützt.Lazy loading is not yet supported by EF Core. Sehen Sie die verzögertes Laden Element auf unseren nachholbedarf dieses Feature zu verfolgen.You can view the lazy loading item on our backlog to track this feature.

Da EF Core wird automatisch ein Fixup-Navigationseigenschaften, Sie Zyklen in Ihre Objektdiagramm ergeben können.Because EF Core will automatically fix-up navigation properties, you can end up with cycles in your object graph. Z. B. beim Laden eines Blogs und bezieht sich Beiträge in einem Blog Objekt führt, die eine Auflistung von Beiträgen verweist.For example, Loading a blog and it's related posts will result in a blog object that references a collection of posts. Jedes dieser Beiträge weist einen Verweis zurück auf den Blog.Each of those posts will have a reference back to the blog.

Einige serialisierungsframeworks lassen sich nicht auf solche Zyklen aus.Some serialization frameworks do not allow such cycles. Json.NET wird z. B. die folgende Ausnahme ausgelöst, ist ein Zyklus auftritt.For example, Json.NET will throw the following exception if a cycle is encoutered.

Newtonsoft.Json.JsonSerializationException: Self-Service verweisen auf Schleife, die mit Typ 'MyApplication.Models.Blog' für Eigenschaft "Blog" erkannt.Newtonsoft.Json.JsonSerializationException: Self referencing loop detected for property 'Blog' with type 'MyApplication.Models.Blog'.

Wenn Sie ASP.NET Core verwenden, können Sie Json.NET um Zyklen zu ignorieren, die im Objektdiagramm gefunden konfigurieren.If you are using ASP.NET Core, you can configure Json.NET to ignore cycles that it finds in the object graph. Dies erfolgt in der ConfigureServices(...) Methode in Startup.cs.This is done in the ConfigureServices(...) method in Startup.cs.

public void ConfigureServices(IServiceCollection services)
{
    ...

    services.AddMvc()
        .AddJsonOptions(
            options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
        );

    ...
}