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.
Entity Framework unterstützt drei Möglichkeiten zum Laden verwandter Daten – eifriges Laden, faules Laden und explizites Laden. Die in diesem Thema gezeigten Techniken gelten gleichermaßen für Modelle, die mit Code First und EF Designer erstellt wurden.
Schnellladen
Beim eager loading handelt es sich um den Prozess, bei dem eine Abfrage eines Entitätstyps verwandte Entitäten ebenfalls als Teil der Abfrage lädt. Eager Loading erfolgt mithilfe der Include-Methode. Die folgenden Abfragen laden beispielsweise Blogs und alle Beiträge, die sich auf jeden Blog beziehen.
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.
Eiferiges Laden mehrerer Ebenen
Es ist auch möglich, mehrere Ebenen verwandter Entitäten eifrig zu laden. In den folgenden Abfragen finden Sie Beispiele dafür, wie Sie dies sowohl für Sammlungs- als auch für Referenznavigationseigenschaften tun.
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 zugehörigen Entitäten geladen werden. Include führt immer alle verwandten Entitäten ein.
Faules Laden
Lazy Loading ist der Prozess, bei dem eine Entität oder eine Sammlung von Entitäten automatisch aus der Datenbank geladen wird, wenn das erste Mal auf eine die Entität/Entitäten referenzierende Eigenschaft zugegriffen wird. Beim Verwenden von POCO-Entitätstypen wird Lazy Loading durch das Erstellen von Instanzen abgeleiteter Proxytypen erreicht, und es werden dann virtuelle Eigenschaften überschrieben, um den Ladevorgang hinzuzufügen. Wenn Sie beispielsweise die unten definierte Blog-Entitätsklasse verwenden, werden die zugehörigen Beiträge beim ersten Zugriff auf die Navigationseigenschaft Beiträge geladen:
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 die Serialisierung deaktivieren
Faules Laden und Serialisierung vertragen sich nicht gut, und wenn Sie nicht sorgfältig sind, können Sie am Ende die gesamte Datenbank abfragen, nur weil das faule Laden aktiviert ist. Die meisten Serialisierer funktionieren, indem sie auf jede Eigenschaft einer Instanz eines Typs zugreifen. Der Eigenschaftenzugriff löst faules Laden aus, sodass mehr Entitäten serialisiert werden. Auf die Eigenschaften dieser Entitäten wird zugegriffen, und weitere Entitäten werden geladen. Es ist ratsam, das Lazy Loading zu deaktivieren, bevor Sie eine Entität serialisieren. In den folgenden Abschnitten wird gezeigt, wie Dies geschieht.
Deaktivieren von Lazy Loading für bestimmte Navigationseigenschaften
Lazy Loading der Postsammlung kann deaktiviert werden, indem die Posts-Eigenschaft nicht virtuell gemacht wird.
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 mit Eager Loading (siehe Eagerly Loading oben) oder der Load-Methode (siehe Explizites Laden unten) erreicht werden.
Deaktivieren des Lazy Loadings für alle Entitäten.
Lazy Loading kann für alle Entitäten im Kontext deaktiviert werden, indem ein Flag in der Konfigurationseigenschaft gesetzt wird. Beispiel:
public class BloggingContext : DbContext
{
public BloggingContext()
{
this.Configuration.LazyLoadingEnabled = false;
}
}
Das Laden verwandter Entitäten kann weiterhin mit gierigem Laden (siehe Gieriges Laden oben) oder der Load-Methode (siehe explizites Laden unten) erreicht werden.
Explizites Laden
Auch wenn das Lazy Loading deaktiviert ist, ist es immer noch möglich, verwandte Entitäten lazy zu laden, aber es muss mit einem expliziten Aufruf erfolgen. Verwenden Sie dazu die Load-Methode für den Eintrag der zugehörigen Entität. Beispiel:
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 Navigationseigenschaft zu einer anderen einzelnen Entität verfügt. Andererseits sollte die Collection-Methode verwendet werden, wenn eine Entität über eine Navigationseigenschaft für eine Sammlung anderer Entitäten verfügt.
Anwenden von Filtern beim expliziten Laden verwandter Entitäten
Die Query-Methode bietet Zugriff auf die zugrunde liegende Abfrage, die Entity Framework beim Laden verwandter Entitäten verwendet. Anschließend können Sie LINQ verwenden, um Filter auf die Abfrage anzuwenden, bevor Sie sie mit einem Aufruf einer LINQ-Erweiterungsmethode wie ToList, Load usw. ausführen. Die Query-Methode kann sowohl mit Verweis- als auch Sammlungsnavigationseigenschaften verwendet werden, ist jedoch am nützlichsten für Sammlungen, in denen sie nur zum Laden eines Teils der Auflistung verwendet werden kann. Beispiel:
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();
}
Bei Verwendung der Query-Methode ist es in der Regel am besten, das Lazy Loading für die Navigationseigenschaft zu deaktivieren. Dies liegt daran, dass andernfalls die gesamte Sammlung entweder vor oder nach der Ausführung der gefilterten Abfrage automatisch vom faulen Lademechanismus geladen wird.
Hinweis
Während die Beziehung als Zeichenfolge anstelle eines Lambda-Ausdrucks angegeben werden kann, ist die zurückgegebene IQueryable nicht generisch, wenn eine Zeichenfolge verwendet wird. Daher wird in der Regel die Cast-Methode benötigt, bevor damit etwas Sinnvolles gemacht werden kann.
Verwenden der Abfrage zum Zählen verwandter Entitäten, ohne sie zu laden
Manchmal ist es hilfreich, zu wissen, wie viele Entitäten mit einer anderen Entität in der Datenbank verbunden sind, ohne dass tatsächlich die Kosten für das Laden aller diese Entitäten entstehen. Die Query-Methode mit der LINQ Count-Methode kann dazu verwendet werden. Beispiel:
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();
}