Query's uitvoeren op meerdere relaties
Verwijzingen naar andere objecten of verzamelingen van andere objecten in uw klassedefinities komen rechtstreeks overeen met relaties met refererende sleutels in de database. U kunt deze relaties gebruiken wanneer u query's uitvoert met behulp van punt notatie voor toegang tot de relatie-eigenschappen en navigeren van het ene object naar het andere. Deze toegangsbewerkingen worden omgezet in complexere joins of gecorreleerde subquery's in de equivalente SQL.
De volgende query navigeert bijvoorbeeld van orders naar klanten als een manier om de resultaten te beperken tot alleen die orders voor klanten die zich in Londen bevinden.
Northwnd db = new Northwnd(@"northwnd.mdf");
IQueryable<Order> londonOrderQuery =
from ord in db.Orders
where ord.Customer.City == "London"
select ord;
Dim db As New Northwnd("c:\northwnd.mdf")
Dim londonOrderQuery = _
From ord In db.Orders _
Where ord.Customer.City = "London" _
Select ord
Als er geen relatie-eigenschappen bestonden, moet u ze handmatig als joins schrijven, net zoals in een SQL-query, zoals in de volgende code:
Northwnd db = new Northwnd(@"northwnd.mdf");
IQueryable<Order> londonOrderQuery =
from cust in db.Customers
join ord in db.Orders on cust.CustomerID equals ord.CustomerID
where cust.City == "London"
select ord;
Dim db As New Northwnd("c:\northwnd.mdf")
Dim londOrderQuery = _
From cust In db.Customers _
Join ord In db.Orders On cust.CustomerID Equals ord.CustomerID _
Select ord
U kunt de relatie-eigenschap gebruiken om deze specifieke relatie eenmalig te definiëren. Vervolgens kunt u de handiger syntaxis van de stip gebruiken. Maar relatie-eigenschappen zijn belangrijker omdat domeinspecifieke objectmodellen doorgaans worden gedefinieerd als hiërarchieën of grafieken. De objecten waarop u programmat, hebben verwijzingen naar andere objecten. Het is slechts een gelukkig toeval dat object-naar-objectrelaties overeenkomen met relaties met refererende sleutels in databases. Toegang tot eigenschappen biedt vervolgens een handige manier om joins te schrijven.
Wat dit betreft, zijn relatie-eigenschappen belangrijker aan de resultatenzijde van een query dan als onderdeel van de query zelf. Nadat de query gegevens over een bepaalde klant heeft opgehaald, geeft de klassedefinitie aan dat klanten orders hebben. Met andere woorden, u verwacht dat de Orders
eigenschap van een bepaalde klant een verzameling is die is gevuld met alle orders van die klant. Dat is in feite het contract dat u hebt gedeclareerd door de klassen op deze manier te definiëren. U verwacht de orders daar te zien, zelfs als de query geen orders heeft aangevraagd. U verwacht dat uw objectmodel een illusie heeft dat het een extensie in het geheugen van de database is met gerelateerde objecten die direct beschikbaar zijn.
Nu u relaties hebt, kunt u query's schrijven door te verwijzen naar de relatie-eigenschappen die in uw klassen zijn gedefinieerd. Deze relatieverwijzingen komen overeen met relaties met refererende sleutels in de database. Bewerkingen die deze relaties gebruiken, worden omgezet in complexere joins in de equivalente SQL. Zolang u een relatie hebt gedefinieerd (met behulp van het AssociationAttribute kenmerk), hoeft u geen expliciete join in LINQ te codeeren naar SQL.
Om deze illusie te behouden, implementeert LINQ in SQL een techniek die uitgesteld laden wordt genoemd. Zie Deferred versus Direct laden voor meer informatie.
Overweeg de volgende SQL-query om een lijst met CustomerID
-OrderID
paren te projecteren:
SELECT t0.CustomerID, t1.OrderID
FROM Customers AS t0 INNER JOIN
Orders AS t1 ON t0.CustomerID = t1.CustomerID
WHERE (t0.City = @p0)
Als u dezelfde resultaten wilt verkrijgen met behulp van LINQ naar SQL, gebruikt u de Orders
eigenschapsreferentie die al in de Customer
klasse bestaat. De Orders
verwijzing bevat de benodigde informatie voor het uitvoeren van de query en het projecteren van de CustomerID
-OrderID
paren, zoals in de volgende code:
Northwnd db = new Northwnd(@"northwnd.mdf");
var idQuery =
from cust in db.Customers
from ord in cust.Orders
where cust.City == "London"
select new { cust.CustomerID, ord.OrderID };
Dim db As New Northwnd("c:\northwnd.mdf")
Dim idQuery = _
From cust In db.Customers, ord In cust.Orders _
Where cust.City = "London" _
Select cust.CustomerID, ord.OrderID
U kunt ook het omgekeerde doen. Dat wil gezegd, u kunt de bijbehorende relatieverwijzing opvragen Orders
en gebruiken Customer
om toegang te krijgen tot informatie over het gekoppelde Customer
object. De volgende code projecteert dezelfde CustomerID
-OrderID
paren als voorheen, maar deze keer door query's uit te voeren Orders
in plaats van Customers
.
Northwnd db = new Northwnd(@"northwnd.mdf");
var idQuery =
from ord in db.Orders
where ord.Customer.City == "London"
select new { ord.Customer.CustomerID, ord.OrderID };
Dim db As New Northwnd("c:\northwnd.mdf")
Dim idQuery = _
From ord In db.Orders _
Where ord.Customer.City = "London" _
Select ord.CustomerID, ord.OrderID