Laden verwandter EntitätenLoading Related Entities

Entity Framework unterstützt drei Möglichkeiten, verwandte Daten Eager Loading, Lazy Loading und expliziten Laden zu laden.Entity Framework supports three ways to load related data - eager loading, lazy loading and explicit loading. Die in diesem Thema dargestellten Techniken gelten jeweils für Modelle, die mit Code First und dem EF-Designer erstellt wurden.The techniques shown in this topic apply equally to models created with Code First and the EF Designer.

Eifrig geladenEagerly Loading

Das unverzügliches Laden ist der Prozess, bei dem eine Abfrage für einen Entitätstyp auch Verwandte Entitäten als Teil der Abfrage lädt.Eager loading is the process whereby a query for one type of entity also loads related entities as part of the query. Das unverzügliches Laden wird durch die Verwendung der Include-Methode erreicht.Eager loading is achieved by use of the Include method. Die nachfolgenden Abfragen laden z. b. Blogs und alle Beiträge im Zusammenhang mit den einzelnen Blogs.For example, the queries below will load blogs and all the posts related to each blog.

using (var context = new BloggingContext())
{
    // Load all blogs and related posts.
    var blogs1 = context.Blogs
                        .Include(b => b.Posts)
                        .ToList();

    // Load one blog and its related posts.
    var blog1 = context.Blogs
                       .Where(b => b.Name == "ADO.NET Blog")
                       .Include(b => b.Posts)
                       .FirstOrDefault();

    // Load all blogs and related posts
    // using a string to specify the relationship.
    var blogs2 = context.Blogs
                        .Include("Posts")
                        .ToList();

    // Load one blog and its related posts
    // using a string to specify the relationship.
    var blog2 = context.Blogs
                       .Where(b => b.Name == "ADO.NET Blog")
                       .Include("Posts")
                       .FirstOrDefault();
}

Hinweis

Include ist eine Erweiterungsmethode im System. Data. Entity-Namespace. Stellen Sie daher sicher, dass Sie diesen Namespace verwenden.Include is an extension method in the System.Data.Entity namespace so make sure you are using that namespace.

Das eifrig Laden mehrerer EbenenEagerly loading multiple levels

Es ist auch möglich, mehrere Ebenen verwandter Entitäten zu laden.It is also possible to eagerly load multiple levels of related entities. Die folgenden Abfragen zeigen Beispiele dazu, wie Sie dies für die Sammlungs-und Verweis Navigations Eigenschaften durchführen können.The queries below show examples of how to do this for both collection and reference navigation properties.

using (var context = new BloggingContext())
{
    // Load all blogs, all related posts, and all related comments.
    var blogs1 = context.Blogs
                        .Include(b => b.Posts.Select(p => p.Comments))
                        .ToList();

    // Load all users, their related profiles, and related avatar.
    var users1 = context.Users
                        .Include(u => u.Profile.Avatar)
                        .ToList();

    // Load all blogs, all related posts, and all related comments  
    // using a string to specify the relationships.
    var blogs2 = context.Blogs
                        .Include("Posts.Comments")
                        .ToList();

    // Load all users, their related profiles, and related avatar  
    // using a string to specify the relationships.
    var users2 = context.Users
                        .Include("Profile.Avatar")
                        .ToList();
}

Hinweis

Es ist derzeit nicht möglich, zu filtern, welche verknüpften Entitäten geladen werden.It is not currently possible to filter which related entities are loaded. Include führt immer alle zugehörigen Entitäten ein.Include will always bring in all related entities.

Lazy LoadingLazy Loading

Lazy Load ist der Prozess, bei dem eine Entität oder eine Auflistung von Entitäten automatisch aus der Datenbank geladen wird, wenn zum ersten Mal auf eine Eigenschaft zugegriffen wird, die auf Entitäten/Entitäten verweist.Lazy loading is the process whereby an entity or collection of entities is automatically loaded from the database the first time that a property referring to the entity/entities is accessed. Wenn poco-Entitäts Typen verwendet werden, wird Lazy Loading durch Erstellen von Instanzen abgeleiteter Proxy Typen und anschließendes Überschreiben von virtuellen Eigenschaften zum Hinzufügen des Lade Hooks erreicht.When using POCO entity types, lazy loading is achieved by creating instances of derived proxy types and then overriding virtual properties to add the loading hook. Wenn Sie z. b. die unten definierte Blog-Entitäts Klasse verwenden, werden die zugehörigen Beiträge beim ersten Zugriff auf die "Posts"-Navigations Eigenschaft geladen:For example, when using the Blog entity class defined below, the related Posts will be loaded the first time the Posts navigation property is accessed:

public class Blog
{
    public int BlogId { get; set; }
    public string Name { get; set; }
    public string Url { get; set; }
    public string Tags { get; set; }

    public virtual ICollection<Post> Posts { get; set; }
}

Lazy Loading für Serialisierung deaktivierenTurn lazy loading off for serialization

Lazy Load und Serialisierung sind nicht gut gemischt, und wenn Sie nicht vorsichtig sind, können Sie die Abfrage für Ihre gesamte Datenbank durchzuführen, da Lazy Loading aktiviert ist.Lazy loading and serialization don’t mix well, and if you aren’t careful you can end up querying for your entire database just because lazy loading is enabled. Die meisten serialisierungsinitialisierer funktionieren, indem Sie auf jede Eigenschaft einer Instanz eines Typs zugreifen.Most serializers work by accessing each property on an instance of a type. Eigenschaften Zugriffs Trigger Lazy Loading, sodass weitere Entitäten serialisiert werden.Property access triggers lazy loading, so more entities get serialized. Auf diesen Entitäten wird zugegriffen, und es werden sogar weitere Entitäten geladen.On those entities properties are accessed, and even more entities are loaded. Es empfiehlt sich, Lazy Loading zu deaktivieren, bevor Sie eine Entität serialisieren.It’s a good practice to turn lazy loading off before you serialize an entity. Dies wird in den folgenden Abschnitte gezeigt.The following sections show how to do this.

Ausschalten Lazy Loading für bestimmte Navigations EigenschaftenTurning off lazy loading for specific navigation properties

Das Lazy Load der Posts-Auflistung kann deaktiviert werden, indem die Posts-Eigenschaft nicht virtuell ist:Lazy loading of the Posts collection can be turned off by making the Posts property non-virtual:

public class Blog
{
    public int BlogId { get; set; }
    public string Name { get; set; }
    public string Url { get; set; }
    public string Tags { get; set; }

    public ICollection<Post> Posts { get; set; }
}

Das Laden der Posts-Auflistung kann weiterhin mithilfe von Eager Loading (siehe das explizite Laden oben) oder der Load-Methode erzielt werden (siehe Explizites Laden unten).Loading of the Posts collection can still be achieved using eager loading (see Eagerly Loading above) or the Load method (see Explicitly Loading below).

Lazy Loading für alle Entitäten deaktivierenTurn off lazy loading for all entities

Lazy Load kann für alle Entitäten im Kontext deaktiviert werden, indem ein Flag für die Konfigurations Eigenschaft festgelegt wird.Lazy loading can be turned off for all entities in the context by setting a flag on the Configuration property. Beispiel:For example:

public class BloggingContext : DbContext
{
    public BloggingContext()
    {
        this.Configuration.LazyLoadingEnabled = false;
    }
}

Das Laden von verknüpften Entitäten kann weiterhin mithilfe von Eager Loading (siehe das explizite Laden oben) oder der Load-Methode erzielt werden (siehe Explizites Laden unten).Loading of related entities can still be achieved using eager loading (see Eagerly Loading above) or the Load method (see Explicitly Loading below).

Explizites LadenExplicitly Loading

Auch wenn Lazy Loading deaktiviert ist, ist es weiterhin möglich, verknüpfte Entitäten verzögert zu laden, aber es muss ein expliziter-Vorgang ausgeführt werden.Even with lazy loading disabled it is still possible to lazily load related entities, but it must be done with an explicit call. Zu diesem Zweck verwenden Sie die Load-Methode für den Eintrag der zugehörigen Entität.To do so you use the Load method on the related entity’s entry. Beispiel:For example:

using (var context = new BloggingContext())
{
    var post = context.Posts.Find(2);

    // Load the blog related to a given post.
    context.Entry(post).Reference(p => p.Blog).Load();

    // Load the blog related to a given post using a string.
    context.Entry(post).Reference("Blog").Load();

    var blog = context.Blogs.Find(1);

    // Load the posts related to a given blog.
    context.Entry(blog).Collection(p => p.Posts).Load();

    // Load the posts related to a given blog
    // using a string to specify the relationship.
    context.Entry(blog).Collection("Posts").Load();
}

Hinweis

Die Reference-Methode sollte verwendet werden, wenn eine Entität über eine Navigations Eigenschaft zu einer anderen einzelnen Entität verfügt.The Reference method should be used when an entity has a navigation property to another single entity. Dagegen sollte die-Auflistungs Methode verwendet werden, wenn eine Entität über eine Navigations Eigenschaft für eine Auflistung von anderen Entitäten verfügt.On the other hand, the Collection method should be used when an entity has a navigation property to a collection of other entities.

Die Query-Methode ermöglicht den Zugriff auf die zugrunde liegende Abfrage, die Entity Framework beim Laden von verknüpften Entitäten verwenden wird.The Query method provides access to the underlying query that Entity Framework will use when loading related entities. Anschließend können Sie mithilfe von LINQ Filter auf die Abfrage anwenden, bevor Sie Sie ausführen, indem Sie eine LINQ-Erweiterungsmethode wie z. b. ToList, Load usw. verwenden. Die Query-Methode kann sowohl mit Verweis-als auch Auflistungs Navigations Eigenschaften verwendet werden, ist jedoch besonders nützlich für Auflistungen, in denen Sie zum Laden von nur einem Teil der Auflistung verwendet werden kann.You can then use LINQ to apply filters to the query before executing it with a call to a LINQ extension method such as ToList, Load, etc. The Query method can be used with both reference and collection navigation properties but is most useful for collections where it can be used to load only part of the collection. Beispiel:For example:

using (var context = new BloggingContext())
{
    var blog = context.Blogs.Find(1);

    // Load the posts with the 'entity-framework' tag related to a given blog.
    context.Entry(blog)
           .Collection(b => b.Posts)
           .Query()
           .Where(p => p.Tags.Contains("entity-framework"))
           .Load();

    // Load the posts with the 'entity-framework' tag related to a given blog
    // using a string to specify the relationship.
    context.Entry(blog)
           .Collection("Posts")
           .Query()
           .Where(p => p.Tags.Contains("entity-framework"))
           .Load();
}

Wenn Sie die Abfrage Methode verwenden, empfiehlt es sich in der Regel, Lazy Loading für die Navigations Eigenschaft zu deaktivieren.When using the Query method it is usually best to turn off lazy loading for the navigation property. Der Grund hierfür ist, dass die gesamte Auflistung möglicherweise automatisch vom Lazy Loading Mechanismus geladen wird, entweder vor oder nach der Ausführung der gefilterten Abfrage.This is because otherwise the entire collection may get loaded automatically by the lazy loading mechanism either before or after the filtered query has been executed.

Hinweis

Obwohl die Beziehung anstelle eines Lambda-Ausdrucks als Zeichenfolge angegeben werden kann, ist das zurückgegebene iquerable-Element nicht generisch, wenn eine Zeichenfolge verwendet wird, sodass die Cast-Methode normalerweise benötigt wird, bevor etwas Nützliches möglich ist.While the relationship can be specified as a string instead of a lambda expression, the returned IQueryable is not generic when a string is used and so the Cast method is usually needed before anything useful can be done with it.

Manchmal ist es hilfreich zu wissen, wie viele Entitäten mit einer anderen Entität in der Datenbank verknüpft sind, ohne dass tatsächlich die Kosten für das Laden all dieser Entitäten anfallen.Sometimes it is useful to know how many entities are related to another entity in the database without actually incurring the cost of loading all those entities. Hierfür kann die Query-Methode mit der LINQ Count-Methode verwendet werden.The Query method with the LINQ Count method can be used to do this. Beispiel:For example:

using (var context = new BloggingContext())
{
    var blog = context.Blogs.Find(1);

    // Count how many posts the blog has.
    var postCount = context.Entry(blog)
                           .Collection(b => b.Posts)
                           .Query()
                           .Count();
}