Uppskjuten kontra omedelbar inläsning
När du frågar efter ett objekt hämtar du faktiskt bara det objekt som du begärde. De relaterade objekten hämtas inte automatiskt samtidigt. (Mer information finns i Fråga mellan relationer.) Du kan inte se att de relaterade objekten inte redan har lästs in, eftersom ett försök att komma åt dem genererar en begäran som hämtar dem.
Du kanske till exempel vill fråga efter en viss uppsättning beställningar och sedan bara ibland skicka ett e-postmeddelande till vissa kunder. Du behöver inte nödvändigtvis först hämta alla kunddata med varje beställning. Du kan använda uppskjuten inläsning för att skjuta upp hämtningen av extra information tills du absolut måste göra det. Ta följande som exempel:
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
Motsatsen kan också vara sant. Du kan ha ett program som måste visa kund- och orderdata samtidigt. Du vet att du behöver båda datauppsättningarna. Du vet att ditt program behöver orderinformation för varje kund så snart du får resultatet. Du vill inte skicka enskilda frågor för beställningar för varje kund. Det du verkligen vill är att hämta orderdata tillsammans med kunderna.
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
Du kan också ansluta kunder och beställningar i en fråga genom att skapa korsprodukten och hämta alla relativa databitar som en stor projektion. Men dessa resultat är inte entiteter. (Mer information finns i LINQ-till-SQL-objektmodellen). Entiteter är objekt som har identitet och som du kan ändra, medan dessa resultat skulle vara projektioner som inte kan ändras och bevaras. Ännu värre är att du skulle hämta massor av redundanta data när varje kund upprepar för varje beställning i utdata för utdata för utplattad koppling.
Det du verkligen behöver är ett sätt att hämta en uppsättning relaterade objekt på samma gång. Uppsättningen är ett avgränsat avsnitt i ett diagram så att du aldrig skulle hämta mer eller mindre än vad som var nödvändigt för den avsedda användningen. För detta ändamål tillhandahåller DataLoadOptions LINQ till SQL omedelbar inläsning av en region i objektmodellen. Metoderna omfattar:
Metoden LoadWith för att omedelbart läsa in data som är relaterade till huvudmålet.
Metoden AssociateWith för att filtrera objekt som hämtats för en viss relation.