Beziehungsübergreifendes Abfragen
Verweise auf andere Objekte oder Auflistungen in Ihren Klassendefinitionen entsprechen direkt den Fremdschlüsselbeziehungen in der Datenbank. Sie können diese Beziehungen nutzen, wenn Sie eine Abfrage mit der dot-Schreibweise vornehmen, um auf die Beziehungseigenschaften zuzugreifen und von einem Objekt zu einem anderen zu navigieren. Diese Zugriffsoperationen werden in komplexere Joins oder korrelierte Unterabfragen in den entsprechenden SQL-Befehlen übersetzt.
Die folgende Abfrage navigiert beispielsweise von Bestellungen zu Kunden und bietet somit die Möglichkeit, die Ergebnisse auf Bestellungen von Kunden aus London einzugrenzen.
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
Wenn keine Beziehungseigenschaften existieren, müssen Sie diese manuell als Joins schreiben, wie Sie es in einer SQL-Abfrage tun würden. Siehe dazu den folgenden 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
Sie können die Eigenschaft Beziehung verwenden, um diese besondere Beziehung einmalig zu definieren. Sie können dann die zweckmäßigere dot-Syntax verwenden. Beziehungseigenschaften sind jedoch vor allem vorhanden, da fachspezifische Objektmodelle i. d. R. als Hierarchien oder Graphen definiert werden. Die Objekte, für die Sie programmieren, verfügen über Verweise auf andere Objekte. Es ist lediglich ein glücklicher Zufall, dass Objekt-zu-Objekt-Beziehungen fremdschlüsselformatierten Beziehungen in Datenbanken entsprechen. Der Eigenschaftenzugriff bietet eine zweckmäßige Möglichkeit, Joins zu schreiben.
Unter diesem Aspekt sind Beziehungseigenschaften auf der Ergebnisseite einer Abfrage wichtiger als auf der Seite der Abfrage selbst. Nachdem die Abfrage Daten zu einem bestimmten Kunden abgerufen hat, gibt die Klassendefinition an, dass der Kunde Bestellungen aufweist. Mit anderen Worten: Sie gehen davon aus, dass die Orders
-Eigenschaft eines bestimmten Kunden eine Auflistung ist, die alle Bestellungen dieses Kunden enthält. Das ist in der Tat der Vertrag, den Sie durch Definition der Klassen auf diese Weise deklariert haben. Sie erwarten, die Bestellungen zu sehen, auch wenn die Abfrage keine Bestellungen abgerufen hat. Sie gehen davon aus, dass Ihr Objektmodell die Illusion erhält, dass es sich um eine im Arbeitsspeicher befindliche Erweiterung der Datenbank handelt, bei der die verwandten Objekte sofort verfügbar sind.
Da Sie nun über Beziehungen verfügen, können Sie Abfragen schreiben, die auf die in Ihren Klassen definierten Beziehungseigenschaften Bezug nehmen. Diese Beziehungsverweise entsprechen Fremdschlüsselbeziehungen in der Datenbank. Operationen, die diese Beziehungen verwenden, werden in komplexere Joins in der entsprechenden SQL übersetzt. Sofern Sie (mit dem AssociationAttribute-Attribut) eine Beziehung definiert haben, müssen Sie in LINQ to SQL keinen expliziten Join codieren.
Um Sie dabei zu unterstützen, diese Illusion aufrechtzuerhalten, implementiert LINQ to SQL eine Technik mit dem Namen verzögertes Laden. Weitere Informationen finden Sie unter Verzögertes und sofortiges Laden.
Verwenden Sie die folgende SQL-Abfrage, um eine Liste von CustomerID
-OrderID
-Paaren zu projizieren:
SELECT t0.CustomerID, t1.OrderID
FROM Customers AS t0 INNER JOIN
Orders AS t1 ON t0.CustomerID = t1.CustomerID
WHERE (t0.City = @p0)
Wenn Sie mit LINQ to SQL die gleichen Ergebnisse erzielen möchten, verwenden Sie den Orders
-Eigenschaftenverweis, der bereits in der Customer
-Klasse existiert. Der Orders
-Verweis bietet die erforderlichen Informationen zum Ausführen der Abfrage und zum Projizieren der CustomerID
-OrderID
-Paare. Siehe hierzu den folgenden 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
Sie können auch umgekehrt vorgehen. In diesem Fall fragen Sie Orders
(Bestellungen) ab und verwenden den Customer
-Beziehungsverweis für den Zugriff auf Informationen zum zugehörigen Customer
-Objekt. Der folgende Code projiziert die gleichen CustomerID
-OrderID
-Paare wie zuvor. In diesem Fall werden jedoch Orders
anstelle von Customers
.abgefragt.
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