Esecuzione di query tra relazioni

I riferimenti ad altri oggetti o raccolte di altri oggetti nelle definizioni della classe corrispondono direttamente alle relazioni di chiavi esterne nel database. È possibile usare queste relazioni quando si esegue una query usando la notazione del punto per accedere alle proprietà della relazione e spostarsi tra gli oggetti. Queste operazioni di accesso vengono convertite in join più complessi o sottoquery correlate nell'equivalente SQL.

Ad esempio, usando la query seguente è possibile spostarsi da ordini a clienti per limitare i risultati solo agli ordini per i clienti residenti nell'area londinese.

        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

Se le proprietà della relazione non esistessero, sarebbe necessario scriverle manualmente come join, esattamente come in una query SQL, come nel codice seguente:

        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

È possibile usare la proprietà della relazione per definire questa particolare relazione una sola volta. quindi usare la più pratica sintassi del punto. Le proprietà della relazione esistono tuttavia soprattutto perché i modelli a oggetti specifici del dominio sono in genere definiti come gerarchie o grafici. Gli oggetti usati nella programmazione dispongono di riferimenti ad altri oggetti. È solo una coincidenza che le relazioni da oggetto a oggetto corrispondano alle relazioni di tipo chiave esterna nei database. L'accesso alle proprietà offre quindi un modo pratico per scrivere join.

A questo riguardo, le proprietà della relazione sono più importanti sul lato dei risultati di una query anziché nella query stessa. Dopo il recupero dei dati su un cliente particolare tramite la query, la definizione della classe indica che sono presenti ordini. In altre parole, si prevede che la proprietà Orders di un particolare cliente sia una raccolta popolata con tutti gli ordini di tale cliente. Si tratta in effetti del contratto dichiarato definendo le classi in questo modo. Si prevede che nei risultati siano inclusi gli ordini, anche se non sono stati espressamente richiesti nella query. Si prevede che il modello a oggetti appaia come un'estensione in memoria del database con gli oggetti correlati immediatamente disponibili.

Dopo avere creato le relazioni, è possibile scrivere query facendo riferimento alle proprietà delle relazioni definite nelle classi. Questi riferimenti alle relazioni corrispondono alle relazioni di chiave esterna nel database. Le operazioni che usano queste relazioni vengono convertite in join più complessi nell'equivalente SQL. A condizione che sia stata definita una relazione usando l'attributo AssociationAttribute, non sarà necessario codificare un join esplicito in LINQ to SQL.

Per mantenere questa apparenza, LINQ to SQL implementa una tecnica detta caricamento lazy. Per altre informazioni, vedere Caricamento lazy e immediato.

Si consideri la query SQL seguente per la proiezione di un elenco di coppie CustomerID-OrderID:

SELECT t0.CustomerID, t1.OrderID  
FROM   Customers AS t0 INNER JOIN  
          Orders AS t1 ON t0.CustomerID = t1.CustomerID  
WHERE  (t0.City = @p0)  

Per ottenere gli stessi risultati tramite LINQ to SQL, usare il riferimento alla proprietà Orders esistente nella classe Customer. Il riferimento a Orders fornisce le informazioni necessarie per eseguire la query e creare una proiezione delle coppie CustomerID-OrderID, come nel codice seguente:

        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

È inoltre possibile procedere in senso inverso, ovvero eseguire una query su Orders e usare il relativo riferimento alla relazione di Customer per accedere alle informazioni sull'oggetto Customer associato. Nel codice seguente vengono proiettate le stesse coppie CustomerID-OrderID come nell'esempio precedente, ma in questo caso eseguendo una query su Orders anziché su 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

Vedi anche