Dela via


Fråga mellan relationer

Referenser till andra objekt eller samlingar av andra objekt i dina klassdefinitioner motsvarar direkt relationer med sekundärnyckel i databasen. Du kan använda dessa relationer när du frågar med hjälp av punkt notation för att komma åt relationsegenskaperna och navigera från ett objekt till ett annat. Dessa åtkomståtgärder översätts till mer komplexa kopplingar eller korrelerade underfrågor i motsvarande SQL.

Följande fråga navigerar till exempel från beställningar till kunder som ett sätt att begränsa resultatet till endast dessa beställningar för kunder i London.

        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

Om relationsegenskaperna inte fanns skulle du behöva skriva dem manuellt som kopplingar, precis som i en SQL-fråga, som i följande kod:

        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

Du kan använda relationsegenskapen för att definiera den här relationen en gång. Du kan sedan använda den mer praktiska punktsyntaxen. Men relationsegenskaper finns ännu viktigare eftersom domänspecifika objektmodeller vanligtvis definieras som hierarkier eller grafer. Objekten som du programmerar mot har referenser till andra objekt. Det är bara ett lyckligt sammanträffande att objekt-till-objekt-relationer motsvarar relationer med sekundärnyckelformat i databaser. Egenskapsåtkomst ger sedan ett bekvämt sätt att skriva kopplingar.

När det gäller detta är relationsegenskaper viktigare på resultatsidan för en fråga än som en del av själva frågan. När frågan har hämtat data om en viss kund anger klassdefinitionen att kunderna har beställningar. Med andra ord förväntar Orders du dig att egenskapen för en viss kund är en samling som fylls med alla beställningar från den kunden. Det är i själva verket det kontrakt som du deklarerade genom att definiera klasserna på detta sätt. Du förväntar dig att se beställningarna där även om frågan inte begärde beställningar. Du förväntar dig att objektmodellen behåller en illusion av att det är ett minnesinternt tillägg av databasen med relaterade objekt omedelbart tillgängliga.

Nu när du har relationer kan du skriva frågor genom att referera till relationsegenskaperna som definierats i dina klasser. Dessa relationsreferenser motsvarar sekundärnyckelrelationer i databasen. Åtgärder som använder dessa relationer översätts till mer komplexa kopplingar i motsvarande SQL. Så länge du har definierat en relation (med attributet AssociationAttribute ) behöver du inte koda en explicit koppling i LINQ till SQL.

För att bevara den här illusionen implementerar LINQ till SQL en teknik som kallas uppskjuten inläsning. Mer information finns i Uppskjuten kontra Omedelbar inläsning.

Överväg följande SQL-fråga för att projicera en lista över CustomerID-OrderID par:

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

Om du vill få samma resultat med hjälp av LINQ till SQL använder du egenskapsreferensen Orders Customer som redan finns i klassen. Referensen Orders innehåller nödvändig information för att köra frågan och projicera paren CustomerID-OrderID , som i följande kod:

        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

Du kan också göra det omvända. Du kan alltså fråga Orders och använda relationsreferensen Customer för att komma åt information om det associerade Customer objektet. Följande kod projicerar samma CustomerID-OrderID par som tidigare, men den här gången genom att Orders fråga i stället för 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

Se även