Uitgestelde versus onmiddellijke laadtijden
Wanneer u een query uitvoert op een object, haalt u eigenlijk alleen het object op dat u hebt aangevraagd. De gerelateerde objecten worden niet automatisch tegelijk opgehaald. (Zie voor meer informatie Query's uitvoeren op meerdere relaties.) U kunt niet zien dat de gerelateerde objecten nog niet zijn geladen, omdat een poging om ze te openen een aanvraag produceert waarmee ze worden opgehaald.
U kunt bijvoorbeeld een query uitvoeren op een bepaalde set orders en vervolgens slechts af en toe een e-mailmelding verzenden naar bepaalde klanten. U hoeft in eerste instantie niet per se alle klantgegevens bij elke bestelling op te halen. U kunt uitgestelde belasting gebruiken om het ophalen van extra informatie uit te stellen totdat u dat absoluut hoeft te doen. Kijk een naar het volgende voorbeeld:
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);
}
}
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
Het tegenovergestelde kan ook waar zijn. Mogelijk hebt u een toepassing die tegelijkertijd klant- en ordergegevens moet bekijken. U weet dat u beide gegevenssets nodig hebt. U weet dat uw toepassing ordergegevens nodig heeft voor elke klant zodra u de resultaten krijgt. U wilt geen afzonderlijke query's indienen voor orders voor elke klant. Wat u echt wilt, is om de ordergegevens samen met de klanten op te halen.
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);
}
}
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
U kunt ook klanten en orders samenvoegen in een query door het cross-product te vormen en alle relatieve bits van gegevens op te halen als één grote projectie. Maar deze resultaten zijn geen entiteiten. (Zie voor meer informatie De LINQ naar het SQL-objectmodel). Entiteiten zijn objecten die identiteit hebben en die u kunt wijzigen, terwijl deze resultaten projecties zijn die niet kunnen worden gewijzigd en behouden. Nog erger, u zou veel redundante gegevens ophalen, omdat elke klant voor elke order herhaalt in de afgevlakte join-uitvoer.
Wat u echt nodig hebt, is een manier om een set gerelateerde objecten tegelijk op te halen. De set is een afgelijnde sectie van een grafiek, zodat u nooit meer of minder zou ophalen dan nodig was voor uw beoogde gebruik. Hiervoor biedt DataLoadOptions LINQ naar SQL direct het laden van een regio van uw objectmodel. Deze methoden zijn onder andere:
De LoadWith methode voor het onmiddellijk laden van gegevens met betrekking tot het hoofddoel.
De AssociateWith methode voor het filteren van objecten die zijn opgehaald voor een bepaalde relatie.