Dotazování napříč relacemi
Odkazy na jiné objekty nebo kolekce jiných objektů v definicích třídy přímo odpovídají relacím cizího klíče v databázi. Tyto relace můžete použít při dotazování pomocí tečky pro přístup k vlastnostem relace a navigaci z jednoho objektu do druhého. Tyto operace přístupu se překládají na složitější spojení nebo korelované poddotazy v ekvivalentním SQL.
Například následující dotaz přejde z objednávek na zákazníky jako způsob, jak omezit výsledky pouze na objednávky pro zákazníky nacházející se v Londýně.
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
Pokud vlastnosti relace neexistovaly, museli byste je zapsat ručně jako spojení, stejně jako byste to udělali v dotazu SQL, jako v následujícím kódu:
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
Vlastnost relace můžete použít k jednorázovému definování této konkrétní relace. Pak můžete použít pohodlnější syntaxi tečky. Vlastnosti vztahů však existují důležitější, protože objektové modely specifické pro doménu jsou obvykle definovány jako hierarchie nebo grafy. Objekty, proti kterým programujete, mají odkazy na jiné objekty. Je to jen šťastná náhoda, že relace mezi objekty odpovídají relacím ve stylu cizího klíče v databázích. Přístup k vlastnostem pak poskytuje pohodlný způsob zápisu spojení.
Pokud jde o tuto možnost, vlastnosti relace jsou důležitější na straně výsledků dotazu než jako součást samotného dotazu. Jakmile dotaz načte data o konkrétním zákazníkovi, definice třídy označuje, že zákazníci mají objednávky. Jinými slovy, očekáváte Orders
, že vlastnost konkrétního zákazníka bude kolekcí naplněnou všemi objednávkami od daného zákazníka. To je ve skutečnosti kontrakt, který jste deklarovali definováním tříd tímto způsobem. Očekáváte, že se tam zobrazí objednávky, i když dotaz nepožádal objednávky. Očekáváte, že váš objektový model zachová iluzi, že se jedná o rozšíření databáze v paměti se souvisejícími objekty, které jsou okamžitě dostupné.
Teď, když máte relace, můžete psát dotazy odkazem na vlastnosti relace definované ve vašich třídách. Tyto odkazy na relace vztahů odpovídají relacím cizího klíče v databázi. Operace, které tyto relace používají, se překládají na složitější spojení v ekvivalentním SQL. Pokud jste definovali relaci (pomocí atributu AssociationAttribute ), nemusíte kódovat explicitní spojení v LINQ to SQL.
Aby se tato iluze zachovala, LINQ to SQL implementuje techniku označovanou jako odložené načítání. Další informace naleznete v tématu Deferred versus Okamžité načítání.
Zvažte následující dotaz SQL pro projektování seznamu párů 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)
Chcete-li získat stejné výsledky pomocí LINQ to SQL, použijte odkaz na Orders
vlastnost již existující ve Customer
třídě. Referenční Orders
informace poskytují potřebné informace ke spuštění dotazu a projektování CustomerID
-OrderID
párů, jako v následujícím kódu:
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
Můžete také provést opak. To znamená, že můžete dotazovat Orders
a použít odkaz na jeho Customer
vztah pro přístup k informacím o přidruženém Customer
objektu. Následující kód projektuje stejné CustomerID
-OrderID
páry jako předtím, ale tentokrát dotazováním Orders
místo .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