Verzögertes und unmittelbares Laden (LINQ to SQL)
Aktualisiert: November 2007
Wenn Sie eine Abfrage für ein Objekt durchführen, wird nur das angeforderte Objekt abgerufen. Die verwandten Objekte werden nicht automatisch zum gleichen Zeitpunkt abgerufen. (Weitere Informationen finden Sie unter Beziehungsübergreifende Abfragen (LINQ to SQL).) Für Sie ist nicht erkennbar, dass verwandte Objekte nicht bereits geladen sind, da der Versuch, auf diese Objekte zuzugreifen, eine Abfrage erzeugt, die diese Objekte abruft.
Sie möchten beispielsweise eine bestimmte Gruppe von Bestellungen abrufen und anschließend bestimmten Kunden eine Benachrichtigung per E-Mail senden. Sie müssen nicht notwendigerweise zunächst alle Kundendaten zu jeder Bestellung abrufen. Sie können mithilfe von verzögertem Laden weitere Informationen erst dann abrufen, wenn Sie diese benötigen. Betrachten Sie das folgende Beispiel:
Dim db As New Northwnd("c:\northwnd.mdf")
Dim notificationQuery = _
From ord In db.Orders _
Where ord.ShipVia = 3 _
Select ord
For Each ordObj As Order In notificationQuery
If ordObj.Freight > 200 Then
SendCustomerNotification(ordObj.Customer)
ProcessOrder(ordObj)
End If
Next
Northwnd db = new Northwnd(@"northwnd.mdf");
IQueryable<Order> notificationQuery =
from ord in db.Orders
where ord.ShipVia == 3
select ord;
foreach (Order ordObj in notificationQuery)
{
if (ordObj.Freight > 200)
SendCustomerNotification(ordObj.Customer);
ProcessOrder(ordObj);
}
}
Das Gegenteil könnte auch zutreffen. Möglicherweise verwenden Sie eine Anwendung, die Kunden- und Bestelldaten gleichzeitig anzeigen muss. Sie wissen, dass Sie beide Datensätze benötigen. Sie wissen, dass die Anwendung Bestellinformationen für jeden Kunden benötigt, sobald Sie die Ergebnisse abrufen. Sie möchten nicht einzelne Abfragen zu den Bestellungen jedes einzelnen Kunden übergeben. Sie möchten stattdessen die Bestelldaten zusammen mit den Kunden abrufen.
Dim db As New Northwnd("c:\northwnd.mdf")
db.DeferredLoadingEnabled = False
Dim custQuery = _
From cust In db.Customers _
Where cust.City = "London" _
Select cust
For Each custObj As Customer In custQuery
For Each ordObj As Order In custObj.Orders
ProcessCustomerOrder(ordObj)
Next
Next
Northwnd db = new Northwnd(@"c:\northwnd.mdf");
db.DeferredLoadingEnabled = false;
IQueryable<Customer> custQuery =
from cust in db.Customers
where cust.City == "London"
select cust;
foreach (Customer custObj in custQuery)
{
foreach (Order ordObj in custObj.Orders)
{
ProcessCustomerOrder(ordObj);
}
}
Sie können auch Kunden und Bestellungen in einer Abfrage zusammenfassen, indem Sie diese produktübergreifend gestalten und alle erforderlichen Daten in Form einer großen Projektion abrufen. Diese Ergebnisse sind jedoch keine Entitäten. (Weitere Informationen finden Sie unter Das LINQ to SQL-Objektmodell.) Entitäten sind Objekte, die Sie verändern können. Bei diesen Ergebnissen handelt es sich jedoch um Projektionen, die nicht verändert und erhalten werden können. Darüber hinaus würden Sie eine Menge redundanter Daten abrufen, da sich die Kunden bei jeder Bestellung in der optimierten gemeinsamen Abfrage wiederholen.
Sie benötigen stattdessen eine Möglichkeit, verwandte Objekte zur gleichen Zeit abzurufen. Dieser Satz ist ein isolierter Bereich eines Graphen, sodass Sie niemals mehr oder weniger Daten als benötigt abrufen. Zu diesem Zweck stellt LINQ to SQL für das sofortige Laden einer Region Ihres Objektmodells DataLoadOptions zur Verfügung. Die Methoden umfassen:
Die LoadWith-Methode zum sofortigen Laden von Daten zum Hauptziel.
Die AssociateWith-Methode zum Filtern abgerufener Objekte nach einer bestimmten Beziehung.