Laden von verknüpften Objekten (Entity Framework)
In diesem Thema werden Muster zum Laden von verknüpften Entitäten beschrieben. Entitätstypen können Navigationseigenschaften definieren, die Zuordnungen im Datenmodell darstellen. Diese Eigenschaften können zum Laden von Entitäten verwendet werden, die mit der von der definierten Zuordnung zurückgegebenen Entität verknüpft sind. Wenn Entitäten auf Grundlage des Datenmodells generiert werden, werden für die Entitäten an beiden Enden einer Zuordnung Navigationseigenschaften generiert. Diese Navigationseigenschaften geben entweder einen Verweis am "1"-Ende einer 1:1- oder einer m:1-Beziehung oder eine Auflistung am "n"-Ende einer 1:n- oder einer m:n-Beziehung zurück. Weitere Informationen finden Sie unter Navigationseigenschaften und Definieren und Verwalten von Beziehungen (Entity Framework).
Die folgenden Muster beschreiben Methoden, die Sie zum Laden von verknüpften Entitäten verwenden können:
Lademuster | Beschreibung |
---|---|
In der Abfrage angegeben |
Sie können eine Entity SQL - oder LINQ to Entities -Abfrage verfassen, mit der Beziehungen mithilfe von Navigationseigenschaften explizit navigiert werden. Wenn Sie eine solche Abfrage ausführen, werden die verknüpften Entitäten zurückgegeben, die als Navigationseigenschaften in der äußersten Projektion der Abfrage enthalten sind. Weitere Informationen finden Sie unter Gewusst wie: Navigieren in Beziehungen mithilfe von Navigationseigenschaften (Entitiy Framework). |
Explizites Laden |
Das explizite Laden von Entitäten in den ObjectContext erfordert zwar mehrere Round-Trips zur Datenbank und möglicherweise mehrere aktive Resultsets. Die zurückgegebene Datenmenge ist jedoch auf die geladenen Entitäten beschränkt. Sie können die Load-Methode für eine EntityCollection oder EntityReference bzw. die LoadProperty-Methode für den ObjectContext verwenden, um die verknüpften Entitäten explizit aus der Datenquelle abzurufen. Jeder Aufruf der Load-Methode öffnet eine Verbindung zur Datenbank, um die verknüpften Informationen abzurufen. Dadurch wird sichergestellt, dass eine Abfrage nicht ohne eine explizite Anforderung der verknüpften Entität ausgeführt wird. Explizites Laden ist das Standardverhalten von Entity Framework .
Hinweis:
Bevor Load aufgerufen wird, werden einige Informationen über die verknüpfte Entität bereits in den ObjectContext geladen.
Weitere Informationen finden Sie in diesem Thema im Abschnitt Explicitly Loading Related Objects. |
Lazy Loading |
Bei diesem Ladetyp werden verknüpfte Entitäten beim Zugriff auf eine Navigationseigenschaft automatisch aus der Datenquelle geladen. Beachten Sie bei diesem Ladetyp, dass jede Navigationseigenschaft, auf die zugegriffen wird, zu einer für die Datenquelle separat ausgeführten Abfrage führt, wenn sich die Entität nicht bereits im ObjectContext befindet. Weitere Informationen finden Sie in diesem Thema im Abschnitt Lazy Loading. |
Eager Loading oder Definieren von Abfragepfaden mit Include |
Wenn die genaue Form des Diagramms von verknüpften Entitäten bekannt ist, die die Anwendung erfordert, können Sie die Include-Methode für die ObjectQuery verwenden, um einen Abfragepfad zu definieren, mit dem gesteuert wird, welche verknüpften Entitäten als Teil der ursprünglichen Abfrage zurückgegeben werden sollen. Beim Definieren eines Abfragepfads ist nur eine Anforderung an die Datenbank erforderlich, um alle vom Pfad definierten Entitäten in einem einzelnen Resultset zurückzugeben. Alle verknüpften Entitäten des im Pfad angegebenen Typs werden mit den einzelnen von der Abfrage zurückgegebenen Objekten geladen. Weitere Informationen finden Sie in diesem Thema im Abschnitt Defining a Query Path to Shape Query Results. |
Explizites Laden von verknüpften Entitätsobjekten
Um verknüpfte Entitäten explizit zu laden, muss die Load-Methode für das von der Navigationseigenschaft zurückgegebene verknüpfte Ende aufgerufen werden. Rufen Sie für eine 1:n-Beziehung die Load-Methode für EntityCollection auf und für eine 1:1-Beziehung die Load-Methode für EntityReference. Wenn Sie mit POCO-Entitäten arbeiten, verwenden Sie die LoadProperty-Methode für den ObjectContext. Weitere Informationen finden Sie unter Laden von verknüpften POCO-Objekten (Entity Framework). Die LoadProperty-Methode kann auch mit Entitäten verwendet werden, die von EntityObject abgeleitet wurden. Mithilfe dieser Methoden werden die Daten der verknüpften Objekte in den Objektkontext geladen. Gibt eine Abfrage Ergebnisse zurück, können Sie die Objekte mit einer foreach-Schleife (For Each...Next in Visual Basic) auflisten und die Load-Methode für die EntityReference-Eigenschaft und die EntityCollection-Eigenschaft für jede Entität in den Ergebnissen bedingt aufrufen.
Hinweis: |
---|
Beim Aufruf der Load-Methode in einer foreach (C#)- oder For Each (Visual Basic)-Enumeration wird von Entity Framework ein neuer Datenleser geöffnet.Diese Operation schlägt fehl, es sei denn, es wurde "Multiple Active Result Sets" aktiviert, indem in der Verbindungszeichenfolge multipleactiveresultsets=true angegeben wurde.Weitere Informationen finden Sie unter Multiple Active Result Sets (MARS) auf MSDN.Das Ergebnis einer Abfrage kann auch in eine List-Auflistung geladen werden. Damit wird der Datenleser geschlossen und das Auflisten zum Laden von Entitäten ermöglicht, auf die verwiesen wird. |
Weitere Informationen finden Sie unter Gewusst wie : Explizites Laden verbundener Objekte (Entity Framework).
Definieren eines Abfragepfads zum Strukturieren von Abfrageergebnissen
Übergeben Sie zum Angeben eines Abfragepfads eine Zeichenfolgendarstellung des Objektdiagramms an die Include-Methode der ObjectQuery. Dieser Pfad gibt an, welche verknüpften Entitäten beim Ausführen einer Objektabfrage zurückgegeben werden sollen. Beispielsweise stellt ein Abfragepfad für eine Abfrage von Contact-Objekten sicher, dass alle verknüpften SalesOrderHeader und SalesOrderDetail zurückgegeben werden. Dies wird in der folgenden Abfrage dargestellt:
' Define a LINQ query with a path that returns
' orders and items for a contact.
Dim contacts = (From contact In context.Contacts.Include("SalesOrderHeaders.SalesOrderDetails") _
Select contact).FirstOrDefault()
// Define a LINQ query with a path that returns
// orders and items for a contact.
var contacts = (from contact in context.Contacts
.Include("SalesOrderHeaders.SalesOrderDetails")
select contact).FirstOrDefault();
Beim Definieren von Abfragepfaden ist Folgendes zu beachten:
Abfragepfade können mit Abfrage-Generator-Methoden und LINQ-Abfragen verwendet werden.
Beim Aufruf von Include ist der Abfragepfad nur für die zurückgegebene Instanz von ObjectQuery gültig. Andere Instanzen von ObjectQuery und der Objektkontext selbst werden nicht beeinflusst.
Da Include das Abfrageobjekt zurückgibt, kann diese Methode mehrmals für eine ObjectQuery aufgerufen werden, um, wie im folgenden Beispiel, Entitäten von mehreren Beziehungen einzuschließen:
' Create a SalesOrderHeader query with two query paths, ' one that returns order items and a second that returns the ' billing and shipping addresses for each order. Dim query As ObjectQuery(Of SalesOrderHeader) = context.SalesOrderHeaders.Include("SalesOrderDetails").Include("Address")
// Create a SalesOrderHeader query with two query paths, // one that returns order items and a second that returns the // billing and shipping addresses for each order. ObjectQuery<SalesOrderHeader> query = context.SalesOrderHeaders.Include("SalesOrderDetails").Include("Address");
Durch die Verwendung von Abfragepfaden können aus scheinbar einfachen Objektabfragen komplexe Befehle werden, die in der Datenquelle ausgeführt werden. Dies tritt auf, da ein oder mehrere Joins erforderlich sind, um verknüpfte Objekte in einer einzelnen Abfrage zurückzugeben. Dies hat für jede verknüpfte, von der Datenquelle zurückgegebene Entität redundante Daten zur Folge. Diese Komplexität nimmt bei Abfragen für ein komplexes Modell (z. B. eine Entität mit Vererbung oder ein Pfad, der m:n-Beziehungen enthält) zu. Mit der ToTraceString-Methode kann der von einer ObjectQuery generierte Befehl angezeigt werden. Wenn ein Abfragepfad zu viele verknüpfte Objekte enthält oder die Objekte zu viele Zeilendaten enthalten, kann die Datenquelle die Abfrage möglicherweise nicht abschließen. Dies tritt auf, wenn die Abfrage temporäre Zwischenspeicherung erfordert, die die Kapazität der Datenquelle überschreitet. In diesem Fall kann die Komplexität der Datenquellenabfrage verringert werden, indem verknüpfte Objekte explizit geladen werden oder verzögertes Laden aktiviert wird. Wenn im Anschluss an die Optimierung einer komplexen Anfrage nach wie vor häufig Timeouts auftreten, sollte möglicherweise der Timeoutwert mithilfe der CommandTimeout-Eigenschaft erhöht werden.
Weitere Informationen finden Sie unter Gewusst wie: Bestimmen von Ergebnissen mit Abfragepfaden (Entity Framework).
Lazy Loading von Entitätsobjekten
Entity Framework unterstützt Lazy Loading für verknüpfte Entitäten. In der Entity Framework -Laufzeit lautet der Wert der LazyLoadingEnabled-Eigenschaft in einer Instanz eines ObjectContext in der Standardeinstellung false. Wenn Sie jedoch die Entity Framework -Tools verwenden, um ein neues Modell und die zugehörigen generierten Klassen zu erstellen, wird LazyLoadingEnabled im Konstruktor des Objektkontexts auf true festgelegt. Ist Lazy Loading aktiviert, werden verknüpfte Entitäten solange nicht aus der Datenquelle geladen, bis der get-Accessor einer Navigationseigenschaft programmgesteuert auf sie zugreift. Zur Deaktivierung von Lazy Loading legen Sie die LazyLoadingEnabled-Eigenschaft in der Instanz von ObjectContextOptions, die von der System.Data.Objects.ObjectContext.ContextOptions-Eigenschaft zurückgegeben wird, auf false fest.
Lazy Loading kann zusammen mit Eager Loading verwendet werden. Auf diese Weise kann ein Basisdatendiagramm mit Abfragepfaden definiert werden, und zusätzliche in den ursprünglichen Abfragepfaden nicht enthaltene verknüpfte Entitäten können nach Bedarf geladen werden. Weitere Informationen finden Sie unter Gewusst wie: Laden von verknüpften Objekten mithilfe von Lazy Loading (Entity Framework).
Beim Verwenden von Lazy Loading sollte Folgendes beachtet werden:
Lazy Loading wird für Navigationseigenschaften unterstützt, die sowohl eine einzelne Entität (z. B. einen EntityReference) als auch eine Auflistung von Entitäten (z. B. eine EntityCollection) zurückgeben.
Ist Lazy Loading aktiviert und eine verknüpfte Entität bereits geladen, wird diese nicht erneut geladen.
Lazy Loading wird für Entitäten in einem Detached-Zustand unterstützt. In diesem Fall werden verknüpfte Objekte ebenfalls in einem Detached-Zustand zurückgegeben.
Lazy Loading-Verhalten wird durch die ObjectContext-Instanz bestimmt, mit der das Objekt aus der Datenquelle (auch wenn die Entität mit dem NoTrackingMergeOption geladen wurde) abgerufen wird oder der das Objekt hinzugefügt oder angefügt wurde. Daher kann das Lazy Loading-Verhalten nicht geändert werden, sobald dieser Kontext freigegeben wurde, und alle weiteren Lazy Loading-Operationen schlagen fehl.
Erwägen Sie beim Serialisieren von Entitäten die Deaktivierung von Lazy Loading. Andernfalls wird Lazy Loading ausgelöst, und die serialisierte Entität enthält ggf. mehr Daten als erwartet.
Erwägen Sie weitere Anpassungen, wenn Sie Lazy Loading mit POCO-Entitäten verwenden. Weitere Informationen finden Sie unter Laden von verknüpften POCO-Objekten (Entity Framework).
Abfragen von verknüpften Entitätsobjekten
Durch das Aufrufen der CreateSourceQuery-Methode für eine EntityCollection können Sie verknüpfte Objekte abfragen, ohne Objekte zuvor in die Auflistung laden zu müssen. CreateSourceQuery gibt einen ObjectQuery zurück der bei der Ausführung den gleichen Satz von Objekten wie beim Aufruf der Load-Methode zurückgibt. Durch das Anwenden von Abfrage-Generator-Methoden auf diese Objektabfrage können in die Auflistung geladene Objekte weiter gefiltert werden. Weitere Informationen finden Sie unter Gewusst wie: Abfragen von verbundenen Objekten in einer EntityCollection (Entity Framework).
Eine ObjectQuery gibt Entitätsdaten als Entitäten zurück. Wenn in der äußersten Abfrageprojektion jedoch eine Navigationseigenschaft enthalten ist, werden von der Abfrage außerdem die verknüpften Entitäten zurückgegeben, auf die von der Navigation zugegriffen wird. Weitere Informationen finden Sie unter Gewusst wie: Navigieren in Beziehungen mithilfe von Navigationseigenschaften (Entitiy Framework).
Überlegungen zur Leistung
Wenn Sie ein Lademuster für verknüpfte Entitäten auswählen, beziehen Sie das Verhalten jeder Methode hinsichtlich der Anzahl und der zeitlichen Steuerung der mit der Datenquelle hergestellten Verbindungen in Ihre Überlegungen mit ein. Wird die Methode der zurückgegebenen Datenmenge und der Komplexität bei Verwendung einer einzelnen Abfrage gerecht? Eager Loading gibt alle verknüpften Entitäten zusammen mit den abgefragten Entitäten in einer einzelnen Abfrage zurück. Da also nur eine Verbindung mit der Datenquelle vorhanden ist, wird in der ursprünglichen Abfrage eine größere Datenmenge zurückgegeben. Zudem führen Abfragepfade zu einer komplexeren Abfrage, da für die Abfrage, die für die Datenquelle ausgeführt wird, zusätzliche Joins erforderlich sind.
Explizites Laden und Lazy Loading ermöglichen das Aufschieben der Anforderung von verknüpften Objektdaten, bis diese Daten wirklich benötigt werden. Die ursprüngliche Abfrage ist so weniger komplex und gibt insgesamt weniger Daten zurück. Jeder darauffolgende Ladevorgang eines verknüpften Objekts stellt jedoch eine Verbindung mit der Datenquelle her und führt eine Abfrage aus. Bei Lazy Loading wird diese Verbindung immer dann hergestellt, wenn auf eine Navigationseigenschaft zugegriffen wird und die verknüpfte Entität noch nicht geladen ist. Wenn Sie hinsichtlich den von der ursprünglichen Abfrage zurückgegebenen verknüpften Entitäten oder der Verwaltung der zeitlichen Steuerung für das Laden von verknüpften Entitäten aus der Datenquelle Bedenken haben, sollten Sie die Deaktivierung von Lazy Loading erwägen. Lazy Loading wird im Konstruktor des von Entity Framework generierten Objektkontexts aktiviert.
Weitere Informationen finden Sie unter Leistungsaspekte (Entity Framework).
Siehe auch
Konzepte
Abfragen eines konzeptionellen Modells (Entity Framework)
Objektabfragen (Entity Framework)
Abfrage-Generator-Methoden (Entity Framework)